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; }