[OpenBIOS] r426 - in openbios-devel: arch/sparc32 drivers

svn at openbios.org svn at openbios.org
Sun Jan 25 13:20:12 CET 2009


Author: blueswirl
Date: 2009-01-25 13:20:12 +0100 (Sun, 25 Jan 2009)
New Revision: 426

Modified:
   openbios-devel/arch/sparc32/entry.S
   openbios-devel/drivers/obio.c
Log:
Use RAM for SMP init instead of NVRAM

Modified: openbios-devel/arch/sparc32/entry.S
===================================================================
--- openbios-devel/arch/sparc32/entry.S	2009-01-25 09:56:08 UTC (rev 425)
+++ openbios-devel/arch/sparc32/entry.S	2009-01-25 12:20:12 UTC (rev 426)
@@ -10,25 +10,19 @@
 #include "psr.h"
 #include "asm/asi.h"
 #include "asm/crs.h"
-#define __ASSEMBLY__
-#include "openbios/firmware_abi.h"
 #define NO_QEMU_PROTOS
 #include "openbios/fw_cfg.h"
 
 #define CFG_ADDR 0x00000510
 #define CFG_ASI  0x2d
 
-#define PHYS_JJ_EEPROM	0x71200000  /* [2000] MK48T08 */
 #define PHYS_JJ_INTR0	0x71E00000  /* CPU0 interrupt control registers */
 
-#define PHYS_SS10_EEPROM	0xf1200000
 #define PHYS_SS10_INTR0 	0xf1400000
 
-#define PHYS_SS2_EEPROM	0xf2000000
 #define PHYS_SS2_INTR0 	0xf5000000
 #define SER_ADDR2       0xf1000004
 
-#define PHYS_SS1000_EEPROM      0x00280000
 #define PHYS_SS1000_SBI         0x02800000
 #define SER_ADDR1000            0x00200004
 
@@ -39,6 +33,40 @@
 	.section ".text", "ax"
 	.align	8
 
+        /* Memory map:
+	 *
+	 * Top +-------------------------+
+	 *     | SMP CPU table           |
+	 *     | s + 0xf00 ... 0xf0f     |
+	 *     | s + 0xf0c valid         |
+	 *     | s + 0xf08 entry         |
+	 *     | s + 0xf04 ctxtbl        |
+	 *     | s + 0xf00 ctx           |
+	 *     +-------------------------+
+	 *     | Bootstrap               |
+	 *     | MMU L3 tables 5 * 0x100 |
+	 *     | s + 0xa00 ... 0xeff     |
+	 *     +-------------------------+
+	 *     | Bootstrap               |
+	 *     | MMU L2 tables 2 * 0x100 |
+	 *     | s + 0x800 ... 0x9ff     |
+	 *     +-------------------------+
+	 *     | Bootstrap               |
+	 *     | MMU L1 table 0x400      |
+	 *     | s + 0x400 ... 0x7ff     |
+	 *     +-------------------------+
+	 *     | Bootstrap               |
+	 *     | MMU L0/ctx table 0x400  |
+	 *     | s + 0x000 ... 0x3ff     |
+	 *     +-------------------------+
+	 *     |                         |
+	 *     | ROM into RAM            |
+	 *     |                         |
+	 *     +-------------------------+
+	 *     :                         :
+	 * Bottom
+	 */
+
 /*
  * Entry point
  * We start execution from here.
@@ -92,6 +120,16 @@
         or      %g3, %g4, %g1
         ! %g1 contains end of memory
 
+
+        ! Start of private memory in %g6
+        set     0x1000, %g3
+        sub     %g1, %g3, %g6
+
+        ! Calculate SMP table location
+        add     %g6, 0xf0c, %g2                 ! valid?
+        lda     [%g2] ASI_M_BYPASS, %g7
+        sta     %g0, [%g2] ASI_M_BYPASS
+
         ! Get machine ID from configuration device
         mov     FW_CFG_MACHINE_ID, %g2
         sub     %g5, 2, %g5
@@ -113,20 +151,12 @@
          nop
 
         ! Ok, this is SS-5
-        ! Find architecture specific part
-        set     PHYS_JJ_EEPROM + OHW_ARCH_PTR, %g5
-        lduha   [%g5] ASI_M_BYPASS, %g2
-        set     PHYS_JJ_EEPROM, %g5
-        add     %g5, %g2, %g3
-        ! Check if this not the first SMP CPU, if so, bypass PROM entirely
-        add     %g3, SPARC_SMP_VALID, %g5
-        lduba   [%g5] ASI_M_BYPASS, %g2
-        stba    %g0, [%g5] ASI_M_BYPASS
-        tst     %g2
+
+        tst     %g7
         bz      first_cpu
          nop
 
-        ! SMP init, jump to user specified address
+        ! Clear softints used for SMP CPU startup
         set     PHYS_JJ_INTR0 + 0x04, %g1
         sll     %g2, 12, %g2
         add     %g1, %g2, %g2
@@ -134,62 +164,41 @@
         sta     %g1, [%g2] ASI_M_BYPASS         ! clear softints
         add     %g2, 4, %g2
         sta     %g0, [%g2] ASI_M_BYPASS         ! clear softints
-        add     %g3, SPARC_SMP_CTXTBL, %g1
-        lda     [%g1] ASI_M_BYPASS, %g2
-        sta     %g0, [%g1] ASI_M_BYPASS
+
+load_ctx:
+        ! SMP init, jump to user specified address
+        add     %g6, 0xf04, %g5                 ! ctxtbl
+        lda     [%g5] ASI_M_BYPASS, %g2
+        sta     %g0, [%g5] ASI_M_BYPASS
         set     AC_M_CTPR, %g1
         sta     %g2, [%g1] ASI_M_MMUREGS        ! set ctx table ptr
-        add     %g3, SPARC_SMP_CTX, %g1
-        lda     [%g1] ASI_M_BYPASS, %g2
-        sta     %g0, [%g1] ASI_M_BYPASS
+        add     %g6, 0xf00, %g5                 ! ctx
+        lda     [%g5] ASI_M_BYPASS, %g2
+        sta     %g0, [%g5] ASI_M_BYPASS
         set     AC_M_CXR, %g1
         sta     %g2, [%g1] ASI_M_MMUREGS        ! set context
-        add     %g3, SPARC_SMP_ENTRY, %g1
-        lda     [%g1] ASI_M_BYPASS, %g2
-        sta     %g0, [%g1] ASI_M_BYPASS
+        add     %g6, 0xf08, %g5                 ! entry
+        lda     [%g5] ASI_M_BYPASS, %g2
+        sta     %g0, [%g5] ASI_M_BYPASS
         set     1, %g1
         jmp     %g2                             ! jump to kernel
          sta    %g1, [%g0] ASI_M_MMUREGS        ! enable mmu
 
 ss10:
         ! Ok, this is SS-10 or SS-600MP
-        ! Find architecture specific part
-        set     PHYS_SS10_EEPROM + OHW_ARCH_PTR, %g5
-        lduha   [%g5] ASI_M_CTL, %g2
-        set     PHYS_SS10_EEPROM, %g5
-        add     %g5, %g2, %g3
-        ! Check if this not the first SMP CPU, if so, bypass PROM entirely
-        add     %g3, SPARC_SMP_VALID, %g5
-        lduba   [%g5] ASI_M_CTL, %g2
-        stba    %g0, [%g5] ASI_M_CTL
-        tst     %g2
+        tst     %g7
         bz      first_cpu
          nop
 
-        ! SMP init, jump to user specified address
+        ! Clear softints used for SMP CPU startup
         set     PHYS_SS10_INTR0 + 0x04, %g1
         sll     %g2, 12, %g2
         add     %g1, %g2, %g2
         set     0xffffffff, %g1
-        sta     %g1, [%g2] ASI_M_CTL         ! clear softints
+        sta     %g1, [%g2] ASI_M_CTL            ! clear softints
         add     %g2, 4, %g2
-        sta     %g0, [%g2] ASI_M_CTL         ! clear softints
-        add     %g3, SPARC_SMP_CTXTBL, %g1
-        lda     [%g1] ASI_M_CTL, %g2
-        sta     %g0, [%g1] ASI_M_CTL
-        set     AC_M_CTPR, %g1
-        sta     %g2, [%g1] ASI_M_MMUREGS        ! set ctx table ptr
-        add     %g3, SPARC_SMP_CTX, %g1
-        lda     [%g1] ASI_M_CTL, %g2
-        sta     %g0, [%g1] ASI_M_CTL
-        set     AC_M_CXR, %g1
-        sta     %g2, [%g1] ASI_M_MMUREGS        ! set context
-        add     %g3, SPARC_SMP_ENTRY, %g1
-        lda     [%g1] ASI_M_CTL, %g2
-        sta     %g0, [%g1] ASI_M_CTL
-        set     1, %g1
-        jmp     %g2                             ! jump to kernel
-         sta    %g1, [%g0] ASI_M_MMUREGS        ! enable mmu
+        b       load_ctx
+         sta    %g0, [%g2] ASI_M_CTL            ! clear softints
 
 ss2:
         ! Ok, this is SS-2
@@ -206,16 +215,11 @@
 first_cpu:
         /* Create temporary page tables and map the ROM area to end of
 	RAM. This will be done properly in iommu.c later. */
-        set     _end, %g3
-        set     0xfff, %g2
-        add     %g3, %g2, %g3
-        andn    %g3, %g2, %g3
-        set     _start, %g2
-        sub     %g3, %g2, %g3
-        set     0x1000, %g4                     ! add 0x1000 for page tables
-        add     %g4, %g3, %g2
-        sub	%g1, %g2, %g2			! start of private memory
-        srl	%g2, 0x4, %g7			! ctx table at s+0x0
+        ! Calculate start of page tables etc. to %g6
+        set     0x1000, %g4
+        sub     %g1, %g4, %g6                   ! start of private memory
+
+        mov     %g6, %g2                        ! ctx table at s+0x0
         add	%g2, 0x400, %g3			! l1 table at s+0x400
         srl	%g3, 0x4, %g3
         or	%g3, 0x1, %g3
@@ -264,7 +268,7 @@
         or	%g3, 0x1, %g3
         sta	%g3, [%g2] ASI_M_BYPASS
         add	%g2, 4, %g2			! s+0x9e0
-        add	%g2, 0xd00 - 0x9e0, %g3		! 5th l3 table for rom at s+0xe00
+        add	%g2, 0xe00 - 0x9e0, %g3		! 5th l3 table for rom at s+0xe00
         srl	%g3, 0x4, %g3
         or	%g3, 0x1, %g3
         sta	%g3, [%g2] ASI_M_BYPASS
@@ -275,10 +279,11 @@
         set	_end, %g6
         set	_start, %g4
         sub     %g6, %g4, %g6
+        sub     %g1, %g6, %g3
+        set	0x1000, %g5
+        sub     %g3, %g5, %g3                   ! start of ROM copy
+        mov     %g3, %g7                        ! save in %g7
         srl     %g6, 12, %g6                    ! # of all pages
-        set	0x1000, %g5
-        sll	%g7, 0x4, %g3
-        add	%g5, %g3, %g3                   ! ctx table + 0x1000
 1:      srl	%g3, 0x4, %g4
         or	%g4, ((7 << 2) | 2), %g4        ! 7 = U: --- S: RWX
         sta	%g4, [%g2] ASI_M_BYPASS
@@ -291,10 +296,8 @@
         mov	%g1, %g6                        ! %g6 = memory size
 
         /* Copy the code, rodata and data sections from ROM. */
-        set	0x1000 - 4, %g4
-        sll	%g7, 0x4, %g3
-        add	%g4, %g3, %g3                   ! ctx table + 0x1000 - 4
-        set	_start - 4, %g4                 ! First address of TEXT
+        sub     %g7, 4, %g3
+        set	_start - 4, %g4                 ! First address of TEXT - 4
         set	_bss, %g5                       ! Last address of DATA
         ba	2f
          nop
@@ -307,8 +310,10 @@
         bl      1b
          add    %g4, 0x4, %g4
 
-
+        set     0x1000, %g3
+        sub     %g6, %g3, %g7                   ! ctx table at s+0x0
         set     AC_M_CTPR, %g2
+        srl     %g7, 4, %g7
         sta     %g7, [%g2] ASI_M_MMUREGS	! set ctx table ptr
         set     AC_M_CXR, %g2
         sta     %g0, [%g2] ASI_M_MMUREGS	! context 0
@@ -350,11 +355,15 @@
         set     qemu_mem_size, %g1
         st      %g6, [%g1]
 
-        sll     %g7, 4, %g7                     ! Store va->pa conversion factor
-        set     _start - 0x1000, %g1
-        sub     %g1, %g7, %g7
+        set     _end, %o0                       ! Store va->pa conversion factor
+        set     _start, %o2
+        sub     %o0, %o2, %o0
+        sub     %g6, %o0, %o0
+        set     0x1000, %o1
+        sub     %o0, %o1, %o0                   ! start of ROM copy
+        sub     %o2, %o0, %o0                   ! start of ROM copy
         set     va_shift, %g1
-        st      %g7, [%g1]
+        st      %o0, [%g1]
 
         set     qemu_machine_type, %g1
         mov     %y, %g2

Modified: openbios-devel/drivers/obio.c
===================================================================
--- openbios-devel/drivers/obio.c	2009-01-25 09:56:08 UTC (rev 425)
+++ openbios-devel/drivers/obio.c	2009-01-25 12:20:12 UTC (rev 426)
@@ -1132,28 +1132,45 @@
     fword("finish-device");
 }
 
+/* SMP CPU boot structure */
+struct smp_cfg {
+    uint32_t smp_ctx;
+    uint32_t smp_ctxtbl;
+    uint32_t smp_entry;
+    uint32_t valid;
+};
+
+static struct smp_cfg *smp_header;
+
 int
 start_cpu(unsigned int pc, unsigned int context_ptr, unsigned int context, int cpu)
 {
-    ohwcfg_v3_t *header = (ohwcfg_v3_t *)nvram;
-    struct sparc_arch_cfg *sparc_header;
-
     if (!cpu)
         return -1;
 
-    sparc_header = (struct sparc_arch_cfg *)&nvram[header->nvram_arch_ptr];
-    sparc_header->smp_entry = pc;
-    sparc_header->smp_ctxtbl = context_ptr;
-    sparc_header->smp_ctx = context;
-    sparc_header->valid = 1;
+    cpu &= 7;
 
-    cpu &= 7;
+    smp_header->smp_entry = pc;
+    smp_header->smp_ctxtbl = context_ptr;
+    smp_header->smp_ctx = context;
+    smp_header->valid = cpu;
+
     intregs->cpu_intregs[cpu].set = SUN4M_SOFT_INT(14);
 
     return 0;
 }
 
+static void
+ob_smp_init(void)
+{
+    unsigned long mem_size;
 
+    // See arch/sparc32/entry.S for memory layout
+    mem_size = fw_cfg_read_i32(FW_CFG_RAM_SIZE);
+    smp_header = (struct smp_cfg *)map_io((uint64_t)(mem_size - 0x100),
+                                          sizeof(struct smp_cfg));
+}
+
 static void
 ob_obio_open(__attribute__((unused))int *idx)
 {
@@ -1276,5 +1293,7 @@
 
     ob_interrupt_init(slavio_base, intr_offset);
 
+    ob_smp_init();
+
     return 0;
 }




More information about the OpenBIOS mailing list