mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
Use RAM for SMP init instead of NVRAM
git-svn-id: svn://coreboot.org/openbios/openbios-devel@426 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
@@ -10,25 +10,19 @@
|
|||||||
#include "psr.h"
|
#include "psr.h"
|
||||||
#include "asm/asi.h"
|
#include "asm/asi.h"
|
||||||
#include "asm/crs.h"
|
#include "asm/crs.h"
|
||||||
#define __ASSEMBLY__
|
|
||||||
#include "openbios/firmware_abi.h"
|
|
||||||
#define NO_QEMU_PROTOS
|
#define NO_QEMU_PROTOS
|
||||||
#include "openbios/fw_cfg.h"
|
#include "openbios/fw_cfg.h"
|
||||||
|
|
||||||
#define CFG_ADDR 0x00000510
|
#define CFG_ADDR 0x00000510
|
||||||
#define CFG_ASI 0x2d
|
#define CFG_ASI 0x2d
|
||||||
|
|
||||||
#define PHYS_JJ_EEPROM 0x71200000 /* [2000] MK48T08 */
|
|
||||||
#define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */
|
#define PHYS_JJ_INTR0 0x71E00000 /* CPU0 interrupt control registers */
|
||||||
|
|
||||||
#define PHYS_SS10_EEPROM 0xf1200000
|
|
||||||
#define PHYS_SS10_INTR0 0xf1400000
|
#define PHYS_SS10_INTR0 0xf1400000
|
||||||
|
|
||||||
#define PHYS_SS2_EEPROM 0xf2000000
|
|
||||||
#define PHYS_SS2_INTR0 0xf5000000
|
#define PHYS_SS2_INTR0 0xf5000000
|
||||||
#define SER_ADDR2 0xf1000004
|
#define SER_ADDR2 0xf1000004
|
||||||
|
|
||||||
#define PHYS_SS1000_EEPROM 0x00280000
|
|
||||||
#define PHYS_SS1000_SBI 0x02800000
|
#define PHYS_SS1000_SBI 0x02800000
|
||||||
#define SER_ADDR1000 0x00200004
|
#define SER_ADDR1000 0x00200004
|
||||||
|
|
||||||
@@ -39,6 +33,40 @@
|
|||||||
.section ".text", "ax"
|
.section ".text", "ax"
|
||||||
.align 8
|
.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
|
* Entry point
|
||||||
* We start execution from here.
|
* We start execution from here.
|
||||||
@@ -92,6 +120,16 @@ entry:
|
|||||||
or %g3, %g4, %g1
|
or %g3, %g4, %g1
|
||||||
! %g1 contains end of memory
|
! %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
|
! Get machine ID from configuration device
|
||||||
mov FW_CFG_MACHINE_ID, %g2
|
mov FW_CFG_MACHINE_ID, %g2
|
||||||
sub %g5, 2, %g5
|
sub %g5, 2, %g5
|
||||||
@@ -113,20 +151,12 @@ entry:
|
|||||||
nop
|
nop
|
||||||
|
|
||||||
! Ok, this is SS-5
|
! Ok, this is SS-5
|
||||||
! Find architecture specific part
|
|
||||||
set PHYS_JJ_EEPROM + OHW_ARCH_PTR, %g5
|
tst %g7
|
||||||
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
|
|
||||||
bz first_cpu
|
bz first_cpu
|
||||||
nop
|
nop
|
||||||
|
|
||||||
! SMP init, jump to user specified address
|
! Clear softints used for SMP CPU startup
|
||||||
set PHYS_JJ_INTR0 + 0x04, %g1
|
set PHYS_JJ_INTR0 + 0x04, %g1
|
||||||
sll %g2, 12, %g2
|
sll %g2, 12, %g2
|
||||||
add %g1, %g2, %g2
|
add %g1, %g2, %g2
|
||||||
@@ -134,62 +164,41 @@ entry:
|
|||||||
sta %g1, [%g2] ASI_M_BYPASS ! clear softints
|
sta %g1, [%g2] ASI_M_BYPASS ! clear softints
|
||||||
add %g2, 4, %g2
|
add %g2, 4, %g2
|
||||||
sta %g0, [%g2] ASI_M_BYPASS ! clear softints
|
sta %g0, [%g2] ASI_M_BYPASS ! clear softints
|
||||||
add %g3, SPARC_SMP_CTXTBL, %g1
|
|
||||||
lda [%g1] ASI_M_BYPASS, %g2
|
load_ctx:
|
||||||
sta %g0, [%g1] ASI_M_BYPASS
|
! 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
|
set AC_M_CTPR, %g1
|
||||||
sta %g2, [%g1] ASI_M_MMUREGS ! set ctx table ptr
|
sta %g2, [%g1] ASI_M_MMUREGS ! set ctx table ptr
|
||||||
add %g3, SPARC_SMP_CTX, %g1
|
add %g6, 0xf00, %g5 ! ctx
|
||||||
lda [%g1] ASI_M_BYPASS, %g2
|
lda [%g5] ASI_M_BYPASS, %g2
|
||||||
sta %g0, [%g1] ASI_M_BYPASS
|
sta %g0, [%g5] ASI_M_BYPASS
|
||||||
set AC_M_CXR, %g1
|
set AC_M_CXR, %g1
|
||||||
sta %g2, [%g1] ASI_M_MMUREGS ! set context
|
sta %g2, [%g1] ASI_M_MMUREGS ! set context
|
||||||
add %g3, SPARC_SMP_ENTRY, %g1
|
add %g6, 0xf08, %g5 ! entry
|
||||||
lda [%g1] ASI_M_BYPASS, %g2
|
lda [%g5] ASI_M_BYPASS, %g2
|
||||||
sta %g0, [%g1] ASI_M_BYPASS
|
sta %g0, [%g5] ASI_M_BYPASS
|
||||||
set 1, %g1
|
set 1, %g1
|
||||||
jmp %g2 ! jump to kernel
|
jmp %g2 ! jump to kernel
|
||||||
sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu
|
sta %g1, [%g0] ASI_M_MMUREGS ! enable mmu
|
||||||
|
|
||||||
ss10:
|
ss10:
|
||||||
! Ok, this is SS-10 or SS-600MP
|
! Ok, this is SS-10 or SS-600MP
|
||||||
! Find architecture specific part
|
tst %g7
|
||||||
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
|
|
||||||
bz first_cpu
|
bz first_cpu
|
||||||
nop
|
nop
|
||||||
|
|
||||||
! SMP init, jump to user specified address
|
! Clear softints used for SMP CPU startup
|
||||||
set PHYS_SS10_INTR0 + 0x04, %g1
|
set PHYS_SS10_INTR0 + 0x04, %g1
|
||||||
sll %g2, 12, %g2
|
sll %g2, 12, %g2
|
||||||
add %g1, %g2, %g2
|
add %g1, %g2, %g2
|
||||||
set 0xffffffff, %g1
|
set 0xffffffff, %g1
|
||||||
sta %g1, [%g2] ASI_M_CTL ! clear softints
|
sta %g1, [%g2] ASI_M_CTL ! clear softints
|
||||||
add %g2, 4, %g2
|
add %g2, 4, %g2
|
||||||
sta %g0, [%g2] ASI_M_CTL ! clear softints
|
b load_ctx
|
||||||
add %g3, SPARC_SMP_CTXTBL, %g1
|
sta %g0, [%g2] ASI_M_CTL ! clear softints
|
||||||
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
|
|
||||||
|
|
||||||
ss2:
|
ss2:
|
||||||
! Ok, this is SS-2
|
! Ok, this is SS-2
|
||||||
@@ -206,16 +215,11 @@ ss1000:
|
|||||||
first_cpu:
|
first_cpu:
|
||||||
/* Create temporary page tables and map the ROM area to end of
|
/* Create temporary page tables and map the ROM area to end of
|
||||||
RAM. This will be done properly in iommu.c later. */
|
RAM. This will be done properly in iommu.c later. */
|
||||||
set _end, %g3
|
! Calculate start of page tables etc. to %g6
|
||||||
set 0xfff, %g2
|
set 0x1000, %g4
|
||||||
add %g3, %g2, %g3
|
sub %g1, %g4, %g6 ! start of private memory
|
||||||
andn %g3, %g2, %g3
|
|
||||||
set _start, %g2
|
mov %g6, %g2 ! ctx table at s+0x0
|
||||||
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
|
|
||||||
add %g2, 0x400, %g3 ! l1 table at s+0x400
|
add %g2, 0x400, %g3 ! l1 table at s+0x400
|
||||||
srl %g3, 0x4, %g3
|
srl %g3, 0x4, %g3
|
||||||
or %g3, 0x1, %g3
|
or %g3, 0x1, %g3
|
||||||
@@ -264,7 +268,7 @@ first_cpu:
|
|||||||
or %g3, 0x1, %g3
|
or %g3, 0x1, %g3
|
||||||
sta %g3, [%g2] ASI_M_BYPASS
|
sta %g3, [%g2] ASI_M_BYPASS
|
||||||
add %g2, 4, %g2 ! s+0x9e0
|
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
|
srl %g3, 0x4, %g3
|
||||||
or %g3, 0x1, %g3
|
or %g3, 0x1, %g3
|
||||||
sta %g3, [%g2] ASI_M_BYPASS
|
sta %g3, [%g2] ASI_M_BYPASS
|
||||||
@@ -275,10 +279,11 @@ first_cpu:
|
|||||||
set _end, %g6
|
set _end, %g6
|
||||||
set _start, %g4
|
set _start, %g4
|
||||||
sub %g6, %g4, %g6
|
sub %g6, %g4, %g6
|
||||||
srl %g6, 12, %g6 ! # of all pages
|
sub %g1, %g6, %g3
|
||||||
set 0x1000, %g5
|
set 0x1000, %g5
|
||||||
sll %g7, 0x4, %g3
|
sub %g3, %g5, %g3 ! start of ROM copy
|
||||||
add %g5, %g3, %g3 ! ctx table + 0x1000
|
mov %g3, %g7 ! save in %g7
|
||||||
|
srl %g6, 12, %g6 ! # of all pages
|
||||||
1: srl %g3, 0x4, %g4
|
1: srl %g3, 0x4, %g4
|
||||||
or %g4, ((7 << 2) | 2), %g4 ! 7 = U: --- S: RWX
|
or %g4, ((7 << 2) | 2), %g4 ! 7 = U: --- S: RWX
|
||||||
sta %g4, [%g2] ASI_M_BYPASS
|
sta %g4, [%g2] ASI_M_BYPASS
|
||||||
@@ -291,10 +296,8 @@ first_cpu:
|
|||||||
mov %g1, %g6 ! %g6 = memory size
|
mov %g1, %g6 ! %g6 = memory size
|
||||||
|
|
||||||
/* Copy the code, rodata and data sections from ROM. */
|
/* Copy the code, rodata and data sections from ROM. */
|
||||||
set 0x1000 - 4, %g4
|
sub %g7, 4, %g3
|
||||||
sll %g7, 0x4, %g3
|
set _start - 4, %g4 ! First address of TEXT - 4
|
||||||
add %g4, %g3, %g3 ! ctx table + 0x1000 - 4
|
|
||||||
set _start - 4, %g4 ! First address of TEXT
|
|
||||||
set _bss, %g5 ! Last address of DATA
|
set _bss, %g5 ! Last address of DATA
|
||||||
ba 2f
|
ba 2f
|
||||||
nop
|
nop
|
||||||
@@ -307,8 +310,10 @@ first_cpu:
|
|||||||
bl 1b
|
bl 1b
|
||||||
add %g4, 0x4, %g4
|
add %g4, 0x4, %g4
|
||||||
|
|
||||||
|
set 0x1000, %g3
|
||||||
|
sub %g6, %g3, %g7 ! ctx table at s+0x0
|
||||||
set AC_M_CTPR, %g2
|
set AC_M_CTPR, %g2
|
||||||
|
srl %g7, 4, %g7
|
||||||
sta %g7, [%g2] ASI_M_MMUREGS ! set ctx table ptr
|
sta %g7, [%g2] ASI_M_MMUREGS ! set ctx table ptr
|
||||||
set AC_M_CXR, %g2
|
set AC_M_CXR, %g2
|
||||||
sta %g0, [%g2] ASI_M_MMUREGS ! context 0
|
sta %g0, [%g2] ASI_M_MMUREGS ! context 0
|
||||||
@@ -350,11 +355,15 @@ highmem:
|
|||||||
set qemu_mem_size, %g1
|
set qemu_mem_size, %g1
|
||||||
st %g6, [%g1]
|
st %g6, [%g1]
|
||||||
|
|
||||||
sll %g7, 4, %g7 ! Store va->pa conversion factor
|
set _end, %o0 ! Store va->pa conversion factor
|
||||||
set _start - 0x1000, %g1
|
set _start, %o2
|
||||||
sub %g1, %g7, %g7
|
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
|
set va_shift, %g1
|
||||||
st %g7, [%g1]
|
st %o0, [%g1]
|
||||||
|
|
||||||
set qemu_machine_type, %g1
|
set qemu_machine_type, %g1
|
||||||
mov %y, %g2
|
mov %y, %g2
|
||||||
|
|||||||
@@ -1132,27 +1132,44 @@ ob_interrupt_init(uint64_t base, unsigned long offset)
|
|||||||
fword("finish-device");
|
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
|
int
|
||||||
start_cpu(unsigned int pc, unsigned int context_ptr, unsigned int context, int cpu)
|
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)
|
if (!cpu)
|
||||||
return -1;
|
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);
|
intregs->cpu_intregs[cpu].set = SUN4M_SOFT_INT(14);
|
||||||
|
|
||||||
return 0;
|
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
|
static void
|
||||||
ob_obio_open(__attribute__((unused))int *idx)
|
ob_obio_open(__attribute__((unused))int *idx)
|
||||||
@@ -1276,5 +1293,7 @@ ob_obio_init(uint64_t slavio_base, unsigned long fd_offset,
|
|||||||
|
|
||||||
ob_interrupt_init(slavio_base, intr_offset);
|
ob_interrupt_init(slavio_base, intr_offset);
|
||||||
|
|
||||||
|
ob_smp_init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user