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