svn commit: r206721 - in head/sys/mips: cavium cavium/dev/rgmii mips

Juli Mallett jmallett at FreeBSD.org
Sat Apr 17 03:08:13 UTC 2010


Author: jmallett
Date: Sat Apr 17 03:08:13 2010
New Revision: 206721
URL: http://svn.freebsd.org/changeset/base/206721

Log:
  o) Add SMP support for Octeon using U-Boot to launch all the processors at the
     same time.
  o) Remove some unused trivial uart functions from octeon_machdep now that the
     uart part is fully working and they are unused.
  o) Use __func__ instead of __FUNCTION__.
  o) Use intr_*() instead of other routines that do the same thing.
  o) Remove some duplicate printfs from the Octeon port, as well as duplicate
     setting of Maxmem.
  o) Use the right frequency divider on Octeon.
  o) Use PCPU_GET(cpuid) consistently to get the cpuid of the running core.
  o) Remove some unused macros in the Octeon port.
  o) Use mips_sync() around use of the global dpcpu, whose value may not be
     visible to APs at first.
  o) When loading the first thread's stack, use macros to make the code correct
     for n64 as well.
  o) Remove stub, do-nothing FAU init/enable/disable functions from the RGMX
     driver.

Added:
  head/sys/mips/cavium/octeon_mp.c   (contents, props changed)
Deleted:
  head/sys/mips/cavium/dev/rgmii/octeon_fau.c
Modified:
  head/sys/mips/cavium/asm_octeon.S
  head/sys/mips/cavium/dev/rgmii/octeon_fau.h
  head/sys/mips/cavium/dev/rgmii/octeon_rgmx.c
  head/sys/mips/cavium/files.octeon1
  head/sys/mips/cavium/octeon_machdep.c
  head/sys/mips/cavium/octeon_pcmap_regs.h
  head/sys/mips/mips/locore.S
  head/sys/mips/mips/mp_machdep.c
  head/sys/mips/mips/mpboot.S

Modified: head/sys/mips/cavium/asm_octeon.S
==============================================================================
--- head/sys/mips/cavium/asm_octeon.S	Sat Apr 17 02:28:28 2010	(r206720)
+++ head/sys/mips/cavium/asm_octeon.S	Sat Apr 17 03:08:13 2010	(r206721)
@@ -1,182 +1,66 @@
-/***********************license start***************
- *  Copyright (c) 2003-2008 Cavium Networks (support at cavium.com). All rights
- *  reserved.
+/*-
+ * Copyright (c) 2004-2010 Juli Mallett <jmallett at FreeBSD.org>
+ * 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.
  *
- *
- *  Redistribution and use in source and binary forms, with or without
- *  modification, are permitted provided that the following conditions are
- *  met:
- *
- *      * Redistributions of source code must retain the above copyright
- *        notice, this list of conditions and the following disclaimer.
- *
- *      * 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.
- *
- *      * Neither the name of Cavium Networks nor the names of
- *        its contributors may be used to endorse or promote products
- *        derived from this software without specific prior written
- *        permission.
- *
- *  TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
- *  AND WITH ALL FAULTS AND CAVIUM NETWORKS MAKES NO PROMISES, REPRESENTATIONS
- *  OR WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH
- *  RESPECT TO THE SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY
- *  REPRESENTATION OR DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT
- *  DEFECTS, AND CAVIUM SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES
- *  OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR
- *  PURPOSE, LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET
- *  POSSESSION OR CORRESPONDENCE TO DESCRIPTION.  THE ENTIRE RISK ARISING OUT
- *  OF USE OR PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
- *
- *
- *  For any questions regarding licensing please contact marketing at caviumnetworks.com
- *
- ***********************license end**************************************/
-
-/* $FreeBSD$ */
+ * $FreeBSD$
+ */
 
 #include <machine/asm.h>
-#include <machine/cache_r4k.h>
-#include <machine/cpuregs.h>
-#include <machine/param.h>
-#include <machine/pte.h>
-
-#include "assym.s"
-	
-
 
-#define CPU_DISABLE_INTERRUPTS(reg, reg2, reg3) \
-        mfc0    reg, MIPS_COP_0_STATUS; \
-        nop; \
-        move    reg3, reg; \
-        li      reg2, ~MIPS_SR_INT_IE; \
-        and     reg, reg2, reg; \
-        mtc0    reg, MIPS_COP_0_STATUS; \
-        COP0_SYNC
+	.set noreorder
 
-
-
-#define CPU_ENABLE_INTERRUPTS(reg, reg3) \
-        mfc0    reg, MIPS_COP_0_STATUS; \
-        nop; \
-        or      reg, reg, reg3; \
-        mtc0    reg, MIPS_COP_0_STATUS; \
-        COP0_SYNC
-
-
-#define PUSHR(reg) \
-        addiu   sp,sp,-16        ; \
-        sd      reg, 8(sp)      ; \
-        nop                     ; 
-
-#define POPR(reg) \
-        ld      reg, 8(sp)      ; \
-        addiu   sp,sp,16        ; \
-        nop                     ; 
-
-
-
-                
+#ifdef SMP
 /*
- * octeon_ciu_get_interrupt_reg_addr
- *
- * Given  Int-X, En-X combination, return the CIU Interrupt Enable Register addr
- * a0 = ciu Int-X:  0/1
- * a1 = ciu EN-0:   0/1
+ * This function must be implemented in assembly because it is called early
+ * in AP boot without a valid stack.
  */
-LEAF(octeon_ciu_get_interrupt_reg_addr)
-        .set    noreorder
-        .set    mips3
-
-        beqz    a0, ciu_get_interrupt_reg_addr_Int_0
-        nop
-
-ciu_get_interrupt_reg_addr_Int_1:
-        beqz    a1, ciu_get_interrupt_reg_addr_Int_1_En_0
-        nop
-
-ciu_get_interrupt_reg_addr_Int_1_En1:
-        li      a0, OCTEON_CIU_ADDR_HI
-        dsll32  a0, a0, 0
-        nop
-        ori      a0, OCTEON_CIU_EN1_INT1_LO
-        j       ciu_get_interrupt_reg_addr_ret
-        nop
-
-ciu_get_interrupt_reg_addr_Int_1_En_0:
-        li      a0, OCTEON_CIU_ADDR_HI
-        dsll32  a0, a0, 0
-        nop
-        ori     a0, OCTEON_CIU_EN0_INT1_LO
-        j       ciu_get_interrupt_reg_addr_ret
-        nop
-
-ciu_get_interrupt_reg_addr_Int_0:
-        beqz    a1, ciu_get_interrupt_reg_addr_Int_0_En_0
-        nop
-
-ciu_get_interrupt_reg_addr_Int_0_En_1:
-        li      a0, OCTEON_CIU_ADDR_HI
-        dsll32  a0, a0, 0
-        nop
-        ori     a0, OCTEON_CIU_EN1_INT0_LO
-        j       ciu_get_interrupt_reg_addr_ret
-        nop
-
-ciu_get_interrupt_reg_addr_Int_0_En_0:
-        li      a0, OCTEON_CIU_ADDR_HI
-        dsll32  a0, a0, 0
-        nop
-        ori     a0, OCTEON_CIU_EN0_INT0_LO
-                
-        
-ciu_get_interrupt_reg_addr_ret: 
-        j       ra
-        nop
-        
-        .set	mips0
-        .set    reorder
-END(octeon_ciu_get_interrupt_reg_addr)
+LEAF(platform_processor_id)
+	.set push
+	.set mips32r2
+	jr	ra
+	rdhwr	v0, $0
+	.set pop
+END(platform_processor_id)
 
-
-                
 /*
- * octeon_ciu_mask_all_interrupts
- *
- * a0 = ciu Interrupt-X:  0/1
- * a1 = ciu Enable-X:   0/1
+ * Called on APs to wait until they are told to launch.
  */
-LEAF(octeon_ciu_mask_all_interrupts)
-	.set    noreorder
-        .set    mips3
-
-        PUSHR(ra)
-        PUSHR(s0)
-        
-        move    t0, a0
-        move    t1, a1
-        li      a0, MIPS_SR_INT_IE
-        CPU_DISABLE_INTERRUPTS(a2, a1, s0)
-        move    a0, t0
-        move    t1, a1
-        jal     octeon_ciu_get_interrupt_reg_addr
-        nop
-        ld      a2, 0(a0)       # Dummy read
-        nop
-        move    a2, zero        # Clear all
-        sd      a2, 0(a0)       # Write new Enable bits
-        nop
-        CPU_ENABLE_INTERRUPTS(a2, s0)
-
-        POPR(s0)
-        POPR(ra)
-	j	ra			# Return
-	nop				# (bd slot)
-
-        .set	mips0
-	.set	reorder
-END(octeon_ciu_mask_all_interrupts)
-
+LEAF(octeon_ap_wait)
+	jal	platform_processor_id
+	nop
+
+1:	ll	t0, octeon_ap_boot
+	bne	v0, t0, 1b
+	nop
+
+	move	t0, zero
+	sc	t0, octeon_ap_boot
+
+	beqz	t0, 1b
+	nop
+
+	j	mpentry
+	nop
+END(octeon_ap_wait)
+#endif

Modified: head/sys/mips/cavium/dev/rgmii/octeon_fau.h
==============================================================================
--- head/sys/mips/cavium/dev/rgmii/octeon_fau.h	Sat Apr 17 02:28:28 2010	(r206720)
+++ head/sys/mips/cavium/dev/rgmii/octeon_fau.h	Sat Apr 17 03:08:13 2010	(r206721)
@@ -217,9 +217,4 @@ static inline void octeon_fau_atomic_add
 }
 
 
-extern void octeon_fau_init(void);
-extern void octeon_fau_enable(void);
-extern void octeon_fau_disable(void);
-
-
 #endif  /* ___OCTEON_FAU__H___ */

Modified: head/sys/mips/cavium/dev/rgmii/octeon_rgmx.c
==============================================================================
--- head/sys/mips/cavium/dev/rgmii/octeon_rgmx.c	Sat Apr 17 02:28:28 2010	(r206720)
+++ head/sys/mips/cavium/dev/rgmii/octeon_rgmx.c	Sat Apr 17 03:08:13 2010	(r206721)
@@ -1481,7 +1481,7 @@ static void octeon_config_hw_units_post_
         oct_write64(OCTEON_POW_WORKQUEUE_INT_THRESHOLD(OCTEON_POW_RX_GROUP_NUM), thr.word64);
 #endif
 
-        ciu_enable_interrupts(OCTEON_CORE_ID, OCTEON_RGMX_CIU_INTX, OCTEON_RGMX_CIU_ENX,
+        ciu_enable_interrupts(PCPU_GET(cpuid), OCTEON_RGMX_CIU_INTX, OCTEON_RGMX_CIU_ENX,
                               (OCTEON_POW_RX_GROUP_MASK |
                                CIU_GENTIMER_BITS_ENABLE(CIU_GENTIMER_NUM_1)), CIU_MIPS_IP2);
 

Modified: head/sys/mips/cavium/files.octeon1
==============================================================================
--- head/sys/mips/cavium/files.octeon1	Sat Apr 17 02:28:28 2010	(r206720)
+++ head/sys/mips/cavium/files.octeon1	Sat Apr 17 03:08:13 2010	(r206721)
@@ -1,8 +1,7 @@
 # $FreeBSD$
 # Octeon Support Files
 #
-mips/mips/mp_machdep.c				optional smp
-mips/cavium/dev/rgmii/octeon_fau.c		optional rgmii
+mips/cavium/asm_octeon.S			optional smp
 mips/cavium/dev/rgmii/octeon_fpa.c		optional rgmii
 mips/cavium/dev/rgmii/octeon_ipd.c 		optional rgmii
 mips/cavium/dev/rgmii/octeon_pko.c		optional rgmii
@@ -10,6 +9,7 @@ mips/cavium/dev/rgmii/octeon_rgmx.c		opt
 mips/cavium/obio.c				optional uart
 mips/cavium/octeon_ebt3000_cf.c			optional cf
 mips/cavium/octeon_machdep.c			standard
+mips/cavium/octeon_mp.c				optional smp
 mips/cavium/uart_bus_octeonusart.c		optional uart
 mips/cavium/uart_cpu_octeonusart.c		optional uart
 mips/cavium/uart_dev_oct16550.c			optional uart

Modified: head/sys/mips/cavium/octeon_machdep.c
==============================================================================
--- head/sys/mips/cavium/octeon_machdep.c	Sat Apr 17 02:28:28 2010	(r206720)
+++ head/sys/mips/cavium/octeon_machdep.c	Sat Apr 17 03:08:13 2010	(r206721)
@@ -111,25 +111,6 @@ platform_reset(void)
 	oct_write64(OCTEON_CIU_SOFT_RST, 1);
 }
 
-
-static inline uint32_t
-octeon_disable_interrupts(void)
-{
-	uint32_t status_bits;
-
-	status_bits = mips_rd_status();
-	mips_wr_status(status_bits & ~MIPS_SR_INT_IE);
-	return (status_bits);
-}
-
-
-static inline void
-octeon_set_interrupts(uint32_t status_bits)
-{
-	mips_wr_status(status_bits);
-}
-
-
 void
 octeon_led_write_char(int char_position, char val)
 {
@@ -203,82 +184,6 @@ octeon_led_run_wheel(int *prog_count, in
 	*prog_count &= 0x7;
 }
 
-#define LSR_DATAREADY        0x01    /* Data ready */
-#define LSR_THRE             0x20    /* Transmit holding register empty */
-#define LSR_TEMT	     0x40    /* Transmitter Empty. THR, TSR & FIFO */
-#define USR_TXFIFO_NOTFULL   0x02    /* Uart TX FIFO Not full */
-
-/*
- * octeon_uart_write_byte
- * 
- * Put out a single byte off of uart port.
- */
-
-void
-octeon_uart_write_byte(int uart_index, uint8_t ch)
-{
-	uint64_t val, val2;
-	if (uart_index < 0 || uart_index > 1)
-		return;
-
-	while (1) {
-		val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400));
-		val2 = oct_read64(OCTEON_MIO_UART0_USR + (uart_index * 0x400));
-		if ((((uint8_t) val) & LSR_THRE) ||
-		    (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) {
-			break;
-		}
-	}
-
-	/* Write the byte */
-	oct_write8(OCTEON_MIO_UART0_THR + (uart_index * 0x400), (uint64_t) ch);
-
-	/* Force Flush the IOBus */
-	oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
-}
-
-
-void
-octeon_uart_write_byte0(uint8_t ch)
-{
-	uint64_t val, val2;
-
-	while (1) {
-		val = oct_read64(OCTEON_MIO_UART0_LSR);
-		val2 = oct_read64(OCTEON_MIO_UART0_USR);
-		if ((((uint8_t) val) & LSR_THRE) ||
-		    (((uint8_t) val2) & USR_TXFIFO_NOTFULL)) {
-			break;
-		}
-	}
-
-	/* Write the byte */
-	oct_write8(OCTEON_MIO_UART0_THR, (uint64_t) ch);
-
-	/* Force Flush the IOBus */
-	oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
-}
-
-/*
- * octeon_uart_write_string
- * 
- */
-void
-octeon_uart_write_string(int uart_index, const char *str)
-{
-	/* Just loop writing one byte at a time */
-    
-	while (*str) {
-		octeon_uart_write_byte(uart_index, *str);
-		if (*str == '\n') {
-			octeon_uart_write_byte(uart_index, '\r');
-		}
-		str++;
-	}
-}
-
-static char wstr[30];
-
 void
 octeon_led_write_hex(uint32_t wl)
 {
@@ -289,44 +194,6 @@ octeon_led_write_hex(uint32_t wl)
 }
 
 
-void octeon_uart_write_hex2(uint32_t wl, uint32_t wh)
-{
-	sprintf(wstr, "0x%X-0x%X  ", wh, wl);
-	octeon_uart_write_string(0, wstr);
-}
-
-void
-octeon_uart_write_hex(uint32_t wl)
-{
-	sprintf(wstr, " 0x%X  ", wl);
-	octeon_uart_write_string(0, wstr);
-}
-
-/*
- * octeon_wait_uart_flush
- */
-void
-octeon_wait_uart_flush(int uart_index, uint8_t ch)
-{
-	uint64_t val;
-	int64_t val3;
-	uint32_t cpu_status_bits;
-
-	if (uart_index < 0 || uart_index > 1)
-		return;
-
-	cpu_status_bits = octeon_disable_interrupts();
-	/* Force Flush the IOBus */
-	oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
-	for (val3 = 0xfffffffff; val3 > 0; val3--) {
-		val = oct_read64(OCTEON_MIO_UART0_LSR + (uart_index * 0x400));
-		if (((uint8_t) val) & LSR_TEMT)
-			break;
-	}
-	octeon_set_interrupts(cpu_status_bits);
-}
-
-
 /*
  * octeon_debug_symbol
  *
@@ -450,17 +317,17 @@ ciu_get_en_reg_addr_new(int corenum, int
 	/* XXX kasserts? */
 	if (enx < CIU_EN_0 || enx > CIU_EN_1) {
 		printf("%s: invalid enx value %d, should be %d or %d\n",
-		    __FUNCTION__, enx, CIU_EN_0, CIU_EN_1);
+		    __func__, enx, CIU_EN_0, CIU_EN_1);
 		return 0;
 	}
 	if (intx < CIU_INT_0 || intx > CIU_INT_1) {
 		printf("%s: invalid intx value %d, should be %d or %d\n",
-		    __FUNCTION__, enx, CIU_INT_0, CIU_INT_1);
+		    __func__, enx, CIU_INT_0, CIU_INT_1);
 		return 0;
 	}
 	if (ciu_ip < CIU_MIPS_IP2 || ciu_ip > CIU_MIPS_IP3) {
 		printf("%s: invalid ciu_ip value %d, should be %d or %d\n",
-		    __FUNCTION__, ciu_ip, CIU_MIPS_IP2, CIU_MIPS_IP3);
+		    __func__, ciu_ip, CIU_MIPS_IP2, CIU_MIPS_IP3);
 		return 0;
 	}
 
@@ -517,7 +384,7 @@ ciu_clear_int_summary(int core_num, int 
 	    core_num, intx, enx, write_bits);
 #endif
 
-	cpu_status_bits = octeon_disable_interrupts();
+	cpu_status_bits = intr_disable();
 
 	ciu_intr_sum_reg_addr = ciu_get_intr_sum_reg_addr(core_num, intx, enx);
 
@@ -535,7 +402,7 @@ ciu_clear_int_summary(int core_num, int 
         printf(" Readback: 0x%llX\n\n   ", (uint64_t) oct_read64(ciu_intr_sum_reg_addr));
 #endif
     
-	octeon_set_interrupts(cpu_status_bits);
+	intr_restore(cpu_status_bits);
 }
 
 /*
@@ -550,7 +417,7 @@ ciu_disable_intr(int core_num, int intx,
 	if (core_num == CIU_THIS_CORE)
         	core_num = octeon_get_core_num();
 
-	cpu_status_bits = octeon_disable_interrupts();
+	cpu_status_bits = intr_disable();
     
 	ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx);
 
@@ -559,7 +426,7 @@ ciu_disable_intr(int core_num, int intx,
 	oct_write64(ciu_intr_reg_addr, 0LL);
 	oct_read64(OCTEON_MIO_BOOT_BIST_STAT);	/* Bus Barrier */
 
-	octeon_set_interrupts(cpu_status_bits);
+	intr_restore(cpu_status_bits);
 }
 
 void
@@ -580,7 +447,7 @@ ciu_dump_interrutps_enabled(int core_num
 #endif
 
         if (!ciu_intr_reg_addr) {
-            printf("Bad call to %s\n", __FUNCTION__);
+            printf("Bad call to %s\n", __func__);
             while(1);
             return;
         }
@@ -612,7 +479,7 @@ void ciu_enable_interrupts(int core_num,
 	    core_num, intx, enx, ciu_ip, set_these_interrupt_bits);
 #endif
 
-	cpu_status_bits = octeon_disable_interrupts();
+	cpu_status_bits = intr_disable();
 
 #ifndef OCTEON_SMP_1
 	ciu_intr_reg_addr = ciu_get_intr_en_reg_addr(core_num, intx, enx);
@@ -621,7 +488,7 @@ void ciu_enable_interrupts(int core_num,
 #endif
 
         if (!ciu_intr_reg_addr) {
-		printf("Bad call to %s\n", __FUNCTION__);
+		printf("Bad call to %s\n", __func__);
 		while(1);
 		return;	/* XXX */
         }
@@ -634,7 +501,7 @@ void ciu_enable_interrupts(int core_num,
 #endif
 	ciu_intr_bits |=  set_these_interrupt_bits;
 	oct_write64(ciu_intr_reg_addr, ciu_intr_bits);
-#ifdef OCTEON_SMP
+#ifdef SMP
 	mips_wbflush();
 #endif
 	oct_read64(OCTEON_MIO_BOOT_BIST_STAT);	/* Bus Barrier */
@@ -644,7 +511,7 @@ void ciu_enable_interrupts(int core_num,
 	    (uint64_t)oct_read64(ciu_intr_reg_addr));
 #endif
 
-	octeon_set_interrupts(cpu_status_bits);
+	intr_restore(cpu_status_bits);
 }
 
 unsigned long
@@ -659,12 +526,8 @@ octeon_memory_init(void)
 	uint32_t realmem_bytes;
 
 	if (octeon_board_real()) {
-		printf("octeon_dram == %jx\n", (intmax_t)octeon_dram);
-		printf("reduced to ram: %u MB", (uint32_t)octeon_dram >> 20);
-
 		realmem_bytes = (octeon_dram - PAGE_SIZE);
 		realmem_bytes &= ~(PAGE_SIZE - 1);
-		printf("Real memory bytes is %x\n", realmem_bytes);
 	} else {
 		/* Simulator we limit to 96 meg */
 		realmem_bytes = (96 << 20);
@@ -678,8 +541,6 @@ octeon_memory_init(void)
 			phys_avail[1] = realmem_bytes;
 		realmem_bytes -= OCTEON_DRAM_FIRST_256_END;
 		realmem_bytes &= ~(PAGE_SIZE - 1);
-		printf("phys_avail[0] = %#lx phys_avail[1] = %#lx\n",
-		       (long)phys_avail[0], (long)phys_avail[1]);
 	} else {
 		/* Simulator gets 96Meg period. */
 		phys_avail[1] = (96 << 20);
@@ -705,23 +566,14 @@ octeon_memory_init(void)
 		realmem_bytes &= ~(PAGE_SIZE - 1);
 		/* Now map the rest of the memory */
 		phys_avail[2] = 0x20000000;
-		printf("realmem_bytes is now at %x\n", realmem_bytes);
 		phys_avail[3] = ((uint32_t) 0x20000000 + realmem_bytes);
-		printf("Next block of memory goes from %#lx to %#lx\n",
-		    (long)phys_avail[2], (long)phys_avail[3]);
 		physmem += btoc(phys_avail[3] - phys_avail[2]);
-	} else {
-		printf("realmem_bytes is %d\n", realmem_bytes);
 	}
 	realmem = physmem;
 
 	printf("Total DRAM Size %#X\n", (uint32_t) octeon_dram);
 	printf("Bank 0 = %#08lX   ->  %#08lX\n", (long)phys_avail[0], (long)phys_avail[1]);
 	printf("Bank 1 = %#08lX   ->  %#08lX\n", (long)phys_avail[2], (long)phys_avail[3]);
-	printf("physmem: %#lx\n", physmem);
-
-	Maxmem = physmem;
-
 }
 
 void
@@ -760,7 +612,15 @@ platform_start(__register_t a0, __regist
 		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
 #endif
 	platform_counter_freq = octeon_get_clock_rate();
-	mips_timer_init_params(platform_counter_freq, 1);
+	mips_timer_init_params(platform_counter_freq, 0);
+
+#ifdef SMP
+	/*
+	 * Clear any pending IPIs and enable the IPI interrupt.
+	 */
+	oct_write64(OCTEON_CIU_MBOX_CLRX(0), 0xffffffff);
+	ciu_enable_interrupts(0, CIU_INT_1, CIU_EN_0, OCTEON_CIU_ENABLE_MBOX_INTR, CIU_MIPS_IP3);
+#endif
 }
 
 /* impSTART: This stuff should move back into the Cavium SDK */
@@ -982,7 +842,7 @@ octeon_boot_params_init(register_t ptr)
 
         printf("Boot Descriptor Ver: %u -> %u/%u",
                octeon_bd_ver, octeon_cvmx_bd_ver/100, octeon_cvmx_bd_ver%100);
-        printf("  CPU clock: %uMHz\n", octeon_cpu_clock/1000000);
+        printf("  CPU clock: %uMHz  Core Mask: %#x\n", octeon_cpu_clock/1000000, octeon_core_mask);
         printf("  Dram: %u MB", (uint32_t)(octeon_dram >> 20));
         printf("  Board Type: %u  Revision: %u/%u\n",
                octeon_board_type, octeon_board_rev_major, octeon_board_rev_minor);

Added: head/sys/mips/cavium/octeon_mp.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/sys/mips/cavium/octeon_mp.c	Sat Apr 17 03:08:13 2010	(r206721)
@@ -0,0 +1,102 @@
+/*-
+ * Copyright (c) 2004-2010 Juli Mallett <jmallett at FreeBSD.org>
+ * 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+
+#include <machine/hwfunc.h>
+#include <machine/smp.h>
+
+#include <mips/cavium/octeon_pcmap_regs.h>
+
+unsigned octeon_ap_boot = ~0;
+
+void
+platform_ipi_send(int cpuid)
+{
+	oct_write64(OCTEON_CIU_MBOX_SETX(cpuid), 1);
+	mips_wbflush();
+}
+
+void
+platform_ipi_clear(void)
+{
+	uint64_t action;
+
+	action = oct_read64(OCTEON_CIU_MBOX_CLRX(PCPU_GET(cpuid)));
+	KASSERT(action == 1, ("unexpected IPIs: %#jx", (uintmax_t)action));
+	oct_write64(OCTEON_CIU_MBOX_CLRX(PCPU_GET(cpuid)), action);
+}
+
+int
+platform_ipi_intrnum(void)
+{
+	return (1);
+}
+
+void
+platform_init_ap(int cpuid)
+{
+	/*
+	 * Set the exception base.
+	 */
+	mips_wr_prid1(0x80000000 | cpuid);
+
+	/*
+	 * Set up interrupts, clear IPIs and unmask the IPI interrupt.
+	 */
+	octeon_ciu_reset();
+
+	oct_write64(OCTEON_CIU_MBOX_CLRX(cpuid), 0xffffffff);
+	ciu_enable_interrupts(cpuid, CIU_INT_1, CIU_EN_0, OCTEON_CIU_ENABLE_MBOX_INTR, CIU_MIPS_IP3);
+
+	mips_wbflush();
+}
+
+int
+platform_num_processors(void)
+{
+	return (fls(octeon_core_mask));
+}
+
+int
+platform_start_ap(int cpuid)
+{
+	if (atomic_cmpset_32(&octeon_ap_boot, ~0, cpuid) == 0)
+		return (-1);
+	for (;;) {
+		DELAY(1000);
+		if (atomic_cmpset_32(&octeon_ap_boot, 0, ~0) != 0)
+			return (0);
+		printf("Waiting for cpu%d to start\n", cpuid);
+	}
+}

Modified: head/sys/mips/cavium/octeon_pcmap_regs.h
==============================================================================
--- head/sys/mips/cavium/octeon_pcmap_regs.h	Sat Apr 17 02:28:28 2010	(r206720)
+++ head/sys/mips/cavium/octeon_pcmap_regs.h	Sat Apr 17 03:08:13 2010	(r206721)
@@ -54,14 +54,6 @@
 
 #ifndef LOCORE
 
-/* XXXimp: From Cavium's include/pcpu.h, need to port that over */
-#ifndef OCTEON_SMP
-#define OCTEON_CORE_ID 0
-#else
-extern struct pcpu *cpuid_to_pcpu[];
-#define OCTEON_CORE_ID (mips_rd_coreid())
-#endif
-
 /*
  * Utility inlines & macros
  */
@@ -324,62 +316,6 @@ static inline void oct_write32 (uint64_t
 #define OCTEON_SCRATCH_2   32
 
 
-static inline uint64_t oct_mf_chord (void)
-{
-    uint64_t dest;
-
-    __asm __volatile (	".set push\n"
-                        ".set noreorder\n"
-                        ".set noat\n"
-                        ".set mips64\n"
-			"dmfc2 $1, 0x400\n"
-                        "move %0, $1\n"
-        		".set pop\n"
- 			: "=r" (dest) :  : "$1");
-    return dest;
-}
-
-
-#define MIPS64_DMFCz(cop,regnum,cp0reg,select)  \
-        .word   (0x40200000 | (cop << 25) | (regnum << 16) | (cp0reg << 11) | select)
-
-
-#define mips64_getcpz_xstr(s) mips64_getcpz_str(s)
-#define mips64_getcpz_str(s) #s
-
-#define mips64_dgetcpz(cop,cpzreg,sel,val_ptr) \
-    ({ __asm __volatile( \
-            ".set push\n" \
-            ".set mips3\n" \
-            ".set noreorder\n" \
-            ".set noat\n" \
-            mips64_getcpz_xstr(MIPS64_DMFCz(cop,1,cpzreg,sel)) "\n" \
-            "nop\n" \
-            "nop\n" \
-            "nop\n" \
-            "nop\n" \
-            "sd $1,0(%0)\n" \
-            ".set pop" \
-            : /* no outputs */ : "r" (val_ptr) : "$1"); \
-    })
-
-
-#define mips64_dgetcp2(cp2reg,sel,retval_ptr) \
-    mips64_dgetcpz(2,cp2reg,sel,retval_ptr)
-
-
-#define OCTEON_MF_CHORD(dest)  mips64_dgetcp2(0x400, 0, &dest)
-
-
-
-#define OCTEON_RDHWR(result, regstr) \
-	__asm __volatile (		\
-        		".set mips3\n"		\
-			"rdhwr %0,$" OCTEON_TMP_STR(regstr) "\n"	\
-        		".set mips\n"		\
-			 : "=d" (result));
-
-#define CVMX_MF_CHORD(dest)         OCTEON_RDHWR(dest, 30)
 
 #define OCTEON_CHORD_HEX(dest_ptr)  \
     ({ __asm __volatile( \
@@ -397,15 +333,6 @@ static inline uint64_t oct_mf_chord (voi
             : /* no outputs */ : "r" (dest_ptr) : "$2"); \
     })
 
-
-
-#define OCTEON_MF_CHORD_BAD(dest)	\
-         __asm __volatile (		\
-        		".set mips3\n"		\
-			"dmfc2 %0, 0x400\n"	\
-        		".set mips0\n"		\
- 			: "=&r" (dest) : )
-
 static inline uint64_t oct_scratch_read64 (uint64_t address)
 {
     return(*((volatile uint64_t *)(OCTEON_SCRATCH_BASE + address)));
@@ -417,17 +344,6 @@ static inline void oct_scratch_write64 (
 }
 
 
-#define OCTEON_READ_CSR32(addr, val) \
-	addr_ptr = addr; \
-	oct_read_32_ptr(&addr_ptr, &val);
-
-#define OCTEON_WRITE_CSR32(addr, val, val_dummy) \
-	addr_ptr = addr; \
-	oct_write_32_ptr(&addr_ptr, &val); \
-	oct_read64(OCTEON_MIO_BOOT_BIST_STAT);
-
-
-
 /*
  * Octeon Address Space Definitions
  */
@@ -791,12 +707,6 @@ extern void octeon_led_write_hexchar(int
 extern void octeon_led_write_hex(uint32_t wl);
 extern void octeon_led_write_string(const char *str);
 extern void octeon_reset(void);
-extern void octeon_uart_write_byte(int uart_index, uint8_t ch);
-extern void octeon_uart_write_string(int uart_index, const char *str);
-extern void octeon_uart_write_hex(uint32_t wl);
-extern void octeon_uart_write_hex2(uint32_t wl, uint32_t wh);
-extern void octeon_wait_uart_flush(int uart_index, uint8_t ch);
-extern void octeon_uart_write_byte0(uint8_t ch);
 extern void octeon_led_write_char0(char val);
 extern void octeon_led_run_wheel(int *pos, int led_position);
 extern void octeon_debug_symbol(void);

Modified: head/sys/mips/mips/locore.S
==============================================================================
--- head/sys/mips/mips/locore.S	Sat Apr 17 02:28:28 2010	(r206720)
+++ head/sys/mips/mips/locore.S	Sat Apr 17 03:08:13 2010	(r206721)
@@ -162,6 +162,18 @@ VECTOR(_locore, unknown)
 	sw	a2, _C_LABEL(fenvp)
 #endif
 
+#if defined(TARGET_OCTEON) && defined(SMP)
+	.set push
+	.set mips32r2
+	rdhwr	t2, $0
+	beqz	t2, 1f
+	nop
+	j	octeon_ap_wait
+	nop
+	.set pop
+1:
+#endif
+
 	/*
 	 * Initialize stack and call machine startup.
 	 */
@@ -178,10 +190,10 @@ VECTOR(_locore, unknown)
 	nop
 
 	PTR_LA	sp, _C_LABEL(thread0)
-	lw      a0, TD_PCB(sp)
-	li	t0, ~7
+	PTR_L	a0, TD_PCB(sp)
+	REG_LI	t0, ~7
 	and	a0, a0, t0
-	subu    sp, a0, CALLFRAME_SIZ
+	PTR_SUBU	sp, a0, CALLFRAME_SIZ
 
 	jal	_C_LABEL(mi_startup)		# mi_startup(frame)
 	sw	zero, CALLFRAME_SIZ - 8(sp)	# Zero out old fp for debugger

Modified: head/sys/mips/mips/mp_machdep.c
==============================================================================
--- head/sys/mips/mips/mp_machdep.c	Sat Apr 17 02:28:28 2010	(r206720)
+++ head/sys/mips/mips/mp_machdep.c	Sat Apr 17 03:08:13 2010	(r206721)
@@ -157,6 +157,8 @@ start_ap(int cpuid)
 	cpus = mp_naps;
 	dpcpu = (void *)kmem_alloc(kernel_map, DPCPU_SIZE);
 
+	mips_sync();
+
 	if (platform_start_ap(cpuid) != 0)
 		return (-1);			/* could not start AP */
 
@@ -246,6 +248,8 @@ smp_init_secondary(u_int32_t cpuid)
 	mips_dcache_wbinv_all();
 	mips_icache_sync_all();
 
+	mips_sync();
+
 	MachSetPID(0);
 
 	pcpu_init(PCPU_ADDR(cpuid), cpuid, sizeof(struct pcpu));

Modified: head/sys/mips/mips/mpboot.S
==============================================================================
--- head/sys/mips/mips/mpboot.S	Sat Apr 17 02:28:28 2010	(r206720)
+++ head/sys/mips/mips/mpboot.S	Sat Apr 17 03:08:13 2010	(r206721)
@@ -36,8 +36,21 @@
 	.set	noat
 	.set	noreorder
 
+#ifdef TARGET_OCTEON
+#define CLEAR_STATUS \
+	mfc0    a0, COP_0_STATUS_REG    ;\
+	li      a2, (MIPS_SR_KX | MIPS_SR_SX | MIPS_SR_UX) ; \
+	or      a0, a0, a2	        ; \
+	li      a2, ~(MIPS_SR_INT_IE | MIPS_SR_EXL | SR_KSU_USER | MIPS_SR_BEV)   ; \
+	and     a0, a0, a2              ; \
+        mtc0    a0, COP_0_STATUS_REG    
+#else
+#define CLEAR_STATUS \
+	mtc0	zero, COP_0_STATUS_REG
+#endif
+
 GLOBAL(mpentry)
-	mtc0	zero, COP_0_STATUS_REG	/* disable interrupts */
+	CLEAR_STATUS			/* disable interrupts */
 
 	mtc0	zero, COP_0_CAUSE_REG	/* clear soft interrupts */
 


More information about the svn-src-all mailing list