Second phase of Hydra attachment: All CPUs are now set up sufficiently that

they can call printf(), which they do before halting.
This commit is contained in:
bjh21 2002-10-05 23:30:03 +00:00
parent 389f612a10
commit bb6b27b143
5 changed files with 221 additions and 25 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: genassym.cf,v 1.2 2001/12/20 01:20:21 thorpej Exp $
# $NetBSD: genassym.cf,v 1.3 2002/10/05 23:30:03 bjh21 Exp $
# Copyright (c) 1982, 1990 The Regents of the University of California.
# All rights reserved.
@ -35,6 +35,7 @@
# SUCH DAMAGE.
include <machine/intr.h>
include <arch/acorn32/acorn32/hydravar.h>
define IH_FUNC offsetof(struct irqhandler, ih_func)
define IH_ARG offsetof(struct irqhandler, ih_arg)
@ -44,3 +45,8 @@ define IH_NUM offsetof(struct irqhandler, ih_num)
define IH_MASKADDR offsetof(struct irqhandler, ih_maskaddr)
define IH_MASKBITS offsetof(struct irqhandler, ih_maskbits)
define IH_NEXT offsetof(struct irqhandler, ih_next)
define HB_TTB offsetof(struct hydraboot_vars, hb_ttb)
define HB_BOOTPAGE_PA offsetof(struct hydraboot_vars, hb_bootpage_pa)
define HB_SP offsetof(struct hydraboot_vars, hb_sp)
define HB_ENTRY offsetof(struct hydraboot_vars, hb_entry)

View File

@ -1,4 +1,4 @@
/* $NetBSD: hydra.c,v 1.6 2002/10/05 13:46:57 bjh21 Exp $ */
/* $NetBSD: hydra.c,v 1.7 2002/10/05 23:30:03 bjh21 Exp $ */
/*-
* Copyright (c) 2002 Ben Harris
@ -29,7 +29,7 @@
#include <sys/param.h>
__KERNEL_RCSID(0, "$NetBSD: hydra.c,v 1.6 2002/10/05 13:46:57 bjh21 Exp $");
__KERNEL_RCSID(0, "$NetBSD: hydra.c,v 1.7 2002/10/05 23:30:03 bjh21 Exp $");
#include <sys/device.h>
#include <sys/systm.h>
@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: hydra.c,v 1.6 2002/10/05 13:46:57 bjh21 Exp $");
#include <arch/arm/mainbus/mainbus.h>
#include <arch/acorn32/acorn32/hydrareg.h>
#include <arch/acorn32/acorn32/hydravar.h>
#include "locators.h"
@ -64,10 +65,19 @@ static void hydra_shutdown(void *);
static void hydra_reset(struct hydra_softc *);
static int cpu_hydra_match(struct device *, struct cfdata *, void *);
static void cpu_hydra_attach(struct device *, struct device *, void *);
static void cpu_hydra_hatch(void);
CFATTACH_DECL(hydra, sizeof(struct hydra_softc),
hydra_match, hydra_attach, NULL, NULL);
CFATTACH_DECL(cpu_hydra, sizeof(struct device),
cpu_hydra_match, cpu_hydra_attach, NULL, NULL);
extern char const hydra_bootcode[], hydra_ebootcode[];
extern char const hydra_probecode[], hydra_eprobecode[];
extern char const hydra_hatchcode[], hydra_ehatchcode[];
static struct hydra_softc *the_hydra;
static int
hydra_match(struct device *parent, struct cfdata *cf, void *aux)
@ -127,6 +137,9 @@ hydra_attach(struct device *parent, struct device *self, void *aux)
bus_space_tag_t iot;
bus_space_handle_t ioh;
if (the_hydra == NULL)
the_hydra = sc;
sc->sc_iot = mba->mb_iot;
if (bus_space_map(sc->sc_iot, HYDRA_PHYS_BASE, HYDRA_PHYS_SIZE, 0,
&sc->sc_ioh) != 0) {
@ -191,8 +204,8 @@ hydra_probe_slave(struct hydra_softc *sc, int slave)
bus_space_handle_t ioh = sc->sc_ioh;
int i, ret;
memcpy((caddr_t)sc->sc_bootpage_va, hydra_bootcode,
hydra_ebootcode - hydra_bootcode);
memcpy((caddr_t)sc->sc_bootpage_va, hydra_probecode,
hydra_eprobecode - hydra_probecode);
bus_space_write_1(iot, ioh, HYDRA_MMU_SET, 1 << slave);
bus_space_write_1(iot, ioh, HYDRA_HALT_SET, 1 << slave);
bus_space_write_1(iot, ioh, HYDRA_RESET, 1 << slave);
@ -269,6 +282,89 @@ hydra_reset(struct hydra_softc *sc)
bus_space_write_1(iot, ioh, HYDRA_MMU_CLR, 0xf);
}
static int
cpu_hydra_match(struct device *parent, struct cfdata *cf, void *aux)
{
/* If there's anything there, it's a CPU. */
return 1;
}
static void
cpu_hydra_attach(struct device *parent, struct device *self, void *aux)
{
struct hydra_softc *sc = (void *)parent;
struct hydra_attach_args *ha = aux;
int slave = ha->ha_slave;
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
int i, ret, error;
vaddr_t uaddr;
struct hydraboot_vars *hb;
/*
* Generate a kernel stack and PCB (in essence, a u-area) for the
* new CPU.
*/
uaddr = uvm_uarea_alloc();
error = uvm_fault_wire(kernel_map, uaddr, uaddr + USPACE,
VM_FAULT_WIRE, VM_PROT_READ | VM_PROT_WRITE);
if (error)
panic("cpu_hydra_attach: uvm_fault_wire failed: %d", error);
/* Copy hatch code to boot page, and set up arguments */
memcpy((caddr_t)sc->sc_bootpage_va, hydra_hatchcode,
hydra_ehatchcode - hydra_hatchcode);
KASSERT(hydra_ehatchcode - hydra_hatchcode <= HYDRABOOT_VARS);
hb = (struct hydraboot_vars *)(sc->sc_bootpage_va + HYDRABOOT_VARS);
hb->hb_ttb = (paddr_t)curproc->p_addr->u_pcb.pcb_pagedir;
hb->hb_bootpage_pa = sc->sc_bootpage_pa;
hb->hb_sp = uaddr + USPACE;
hb->hb_entry = &cpu_hydra_hatch;
cpu_drain_writebuf();
bus_space_write_1(iot, ioh, HYDRA_MMU_SET, 1 << slave);
bus_space_write_1(iot, ioh, HYDRA_HALT_SET, 1 << slave);
bus_space_write_1(iot, ioh, HYDRA_RESET, 1 << slave);
bus_space_write_1(iot, ioh, HYDRA_HALT_CLR, 1 << slave);
bus_space_write_1(iot, ioh, HYDRA_RESET, 0);
ret = 0;
for (i = 0; i < 100000; i++) {
if ((bus_space_read_1(iot, ioh, HYDRA_HALT_STATUS) &
(1 << slave)) != 0) {
ret = 1;
break;
}
}
bus_space_write_1(iot, ioh, HYDRA_HALT_SET, 1 << slave);
bus_space_write_1(iot, ioh, HYDRA_MMU_CLR, 1 << slave);
cpu_dcache_inv_range((vaddr_t)hb, sizeof(*hb));
if (ret == 0) {
printf(": failed to spin up\n");
return;
}
printf("\n");
}
static void
cpu_hydra_hatch(void)
{
struct hydra_softc *sc = the_hydra;
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
int slave;
slave = bus_space_read_1(iot, ioh, HYDRA_ID_STATUS) & 0x3;
printf(": Number %d is alive!", slave);
bus_space_write_1(iot, ioh, HYDRA_HALT_SET, 1 << slave);
/* We only get here if someone resumes us. */
for (;;)
continue;
}
#ifdef MULTIPROCESSOR
void
cpu_boot_secondary_processors(void)

View File

@ -1,4 +1,4 @@
/* $NetBSD: hydra_boot.S,v 1.1 2002/09/30 23:22:05 bjh21 Exp $ */
/* $NetBSD: hydra_boot.S,v 1.2 2002/10/05 23:30:03 bjh21 Exp $ */
/*-
* Copyright (c) 2002 Ben Harris
@ -31,28 +31,20 @@
* hydra_boot.S - Code to run on a Hydra slave CPU when it comes out of reset.
*/
#include "assym.h"
#include <machine/asm.h>
#include <arm/armreg.h>
#include <arch/acorn32/acorn32/hydrareg.h>
#include <arch/acorn32/acorn32/hydravar.h>
RCSID("$NetBSD: hydra_boot.S,v 1.1 2002/09/30 23:22:05 bjh21 Exp $")
RCSID("$NetBSD: hydra_boot.S,v 1.2 2002/10/05 23:30:03 bjh21 Exp $")
ENTRY_NP(hydra_bootcode)
ENTRY_NP(hydra_probecode)
/*
* This code is mapped in at physical address zero when a CPU
* hatches, so it forms the vector table until the Hydra MMU
* is turned off and the CPU MMU is turned on. Any exception
* apart from a reset just puts us in a tight loop.
* is probed. It just halts the CPU as quickly as possible.
*/
b Lhydra_reset /* Reset */
b . /* Undefined instruction */
b . /* SWI */
b . /* Prefetch abort */
b . /* Data abort */
b . /* Address exception */
b . /* IRQ */
b . /* FIQ */
Lhydra_reset:
mov r0, #HYDRA_PHYS_BASE
ldr r1, [r0, #(HYDRA_ID_STATUS << 2)]
and r1, r1, #3 /* Mask off slave ID */
@ -62,5 +54,63 @@ Lhydra_reset:
b . /* Get here if we're released */
.align 0
.global _C_LABEL(hydra_ebootcode)
_C_LABEL(hydra_ebootcode):
.global _C_LABEL(hydra_eprobecode)
_C_LABEL(hydra_eprobecode):
/* Code called when spinning up a slave CPU for real. */
ENTRY_NP(hydra_hatchcode)
/*
* r0-r3: scratch
* r4: &hydraboot_vars
* r5: control reg
*/
mov r4, #HYDRABOOT_VARS
/* Enable 32-bit program and data space. */
mov r5, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE)
mcr p15, 0, r5, c1, c0, 0
/* Switch to SVC32 mode. */
mrs r0, cpsr
bic r0, r0, #PSR_MODE
orr r0, r0, #PSR_SVC32_MODE
msr cpsr_c, r0
/* Switch to using the real physical address for this page. */
ldr r0, [r4, #HB_BOOTPAGE_PA]
add r4, r4, r0
add pc, pc, r0
mov r0, r0
mov r0, r0
/* Disable Hydra MMU for this processor. */
mov r0, #HYDRA_PHYS_BASE
ldr r1, [r0, #(HYDRA_ID_STATUS << 2)]
and r1, r1, #3 /* Mask off slave ID */
mov r2, #1
mov r2, r2, lsl r1 /* Get the bit for this CPU */
str r2, [r0, #(HYDRA_MMU_CLR << 2)] /* Disable MMU */
/* Set TTB */
ldr r0, [r4, #HB_TTB]
mcr p15, 0, r0, c2, c0, 0
/* Flush TLB */
mov r0, #0
mcr p15, 0, r0, c5, c0, 0
/* Get start address */
ldr r0, [r4, #HB_ENTRY]
/* Set up stack */
ldr sp, [r4, #HB_SP]
mov fp, #0
mov lr, #0
/* Enable MMU */
orr r5, r5, #CPU_CONTROL_MMU_ENABLE
orr r5, r5, #CPU_CONTROL_SYST_ENABLE
mcr p15, 0, r5, c1, c0, 0
/* Run away before the pipeline runs out */
mov pc, r0
b .
.align 0
.global _C_LABEL(hydra_ehatchcode)
_C_LABEL(hydra_ehatchcode):

View File

@ -0,0 +1,43 @@
/* $NetBSD: hydravar.h,v 1.1 2002/10/05 23:30:03 bjh21 Exp $ */
/*-
* Copyright (c) 2002 Ben Harris
* 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
*/
/*
* Variables in the Hydra boot page used to pass critical data to a
* newly-hatched CPU.
*/
#define HYDRABOOT_VARS 0x0f00
#ifndef _LOCORE
struct hydraboot_vars {
paddr_t hb_ttb;
paddr_t hb_bootpage_pa;
register_t hb_sp;
void (*hb_entry)(void);
};
#endif

View File

@ -1,4 +1,4 @@
# $NetBSD: files.acorn32,v 1.15 2002/09/30 23:22:06 bjh21 Exp $
# $NetBSD: files.acorn32,v 1.16 2002/10/05 23:30:03 bjh21 Exp $
#
# First try for arm-specific configuration info
#
@ -21,6 +21,7 @@ file dev/isa/isadma.c isadma needs-flag
# Simtec Hydra multiprocessor system
device hydra { slave = -1 }
attach hydra at mainbus
attach cpu at hydra with cpu_hydra
file arch/acorn32/acorn32/hydra.c hydra needs-flag
file arch/acorn32/acorn32/hydra_boot.S hydra needs-flag