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 (supp...@cavium.com). All rights
- *  reserved.
+/*-
+ * Copyright (c) 2004-2010 Juli Mallett <jmall...@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 
market...@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 <jmall...@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 */
 
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to