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:
parent
389f612a10
commit
bb6b27b143
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue