Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/acorn32 Second phase of Hydra attachment: All CPUs...
details: https://anonhg.NetBSD.org/src/rev/6625264bc38d
branches: trunk
changeset: 537807:6625264bc38d
user: bjh21 <bjh21%NetBSD.org@localhost>
date: Sat Oct 05 23:30:03 2002 +0000
description:
Second phase of Hydra attachment: All CPUs are now set up sufficiently that
they can call printf(), which they do before halting.
diffstat:
sys/arch/acorn32/acorn32/genassym.cf | 8 ++-
sys/arch/acorn32/acorn32/hydra.c | 106 ++++++++++++++++++++++++++++++++-
sys/arch/acorn32/acorn32/hydra_boot.S | 90 ++++++++++++++++++++++------
sys/arch/acorn32/acorn32/hydravar.h | 43 +++++++++++++
sys/arch/acorn32/conf/files.acorn32 | 3 +-
5 files changed, 223 insertions(+), 27 deletions(-)
diffs (truncated from 361 to 300 lines):
diff -r 4e537de9f903 -r 6625264bc38d sys/arch/acorn32/acorn32/genassym.cf
--- a/sys/arch/acorn32/acorn32/genassym.cf Sat Oct 05 23:26:48 2002 +0000
+++ b/sys/arch/acorn32/acorn32/genassym.cf Sat Oct 05 23:30:03 2002 +0000
@@ -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_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)
diff -r 4e537de9f903 -r 6625264bc38d sys/arch/acorn32/acorn32/hydra.c
--- a/sys/arch/acorn32/acorn32/hydra.c Sat Oct 05 23:26:48 2002 +0000
+++ b/sys/arch/acorn32/acorn32/hydra.c Sat Oct 05 23:30:03 2002 +0000
@@ -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 @@
#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_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 @@
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 @@
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 @@
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)
diff -r 4e537de9f903 -r 6625264bc38d sys/arch/acorn32/acorn32/hydra_boot.S
--- a/sys/arch/acorn32/acorn32/hydra_boot.S Sat Oct 05 23:26:48 2002 +0000
+++ b/sys/arch/acorn32/acorn32/hydra_boot.S Sat Oct 05 23:30:03 2002 +0000
@@ -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 <machine/asm.h>
-#include <arch/acorn32/acorn32/hydrareg.h>
+#include "assym.h"
-RCSID("$NetBSD: hydra_boot.S,v 1.1 2002/09/30 23:22:05 bjh21 Exp $")
+#include <machine/asm.h>
+#include <arm/armreg.h>
+#include <arch/acorn32/acorn32/hydrareg.h>
+#include <arch/acorn32/acorn32/hydravar.h>
-ENTRY_NP(hydra_bootcode)
+RCSID("$NetBSD: hydra_boot.S,v 1.2 2002/10/05 23:30:03 bjh21 Exp $")
+
+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 @@
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):
diff -r 4e537de9f903 -r 6625264bc38d sys/arch/acorn32/acorn32/hydravar.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/acorn32/acorn32/hydravar.h Sat Oct 05 23:30:03 2002 +0000
Home |
Main Index |
Thread Index |
Old Index