File: [local] / sys / arch / vax / vax / locore.c (download)
Revision 1.1.1.1 (vendor branch), Tue Mar 4 16:08:47 2008 UTC (16 years, 3 months ago) by nbrk
Branch: OPENBSD_4_2_BASE, MAIN
CVS Tags: jornada-partial-support-wip, HEAD Changes since 1.1: +0 -0 lines
Import of OpenBSD 4.2 release kernel tree with initial code to support
Jornada 720/728, StrongARM 1110-based handheld PC.
At this point kernel roots on NFS and boots into vfs_mountroot() and traps.
What is supported:
- glass console, Jornada framebuffer (jfb) works in 16bpp direct color mode
(needs some palette tweaks for non black/white/blue colors, i think)
- saic, SA11x0 interrupt controller (needs cleanup)
- sacom, SA11x0 UART (supported only as boot console for now)
- SA11x0 GPIO controller fully supported (but can't handle multiple interrupt
handlers on one gpio pin)
- sassp, SSP port on SA11x0 that attaches spibus
- Jornada microcontroller (jmcu) to control kbd, battery, etc throught
the SPI bus (wskbd attaches on jmcu, but not tested)
- tod functions seem work
- initial code for SA-1111 (chip companion) : this is TODO
Next important steps, i think:
- gpio and intc on sa1111
- pcmcia support for sa11x0 (and sa1111 help logic)
- REAL root on nfs when we have PCMCIA support (we may use any of supported pccard NICs)
- root on wd0! (using already supported PCMCIA-ATA)
|
/* $OpenBSD: locore.c,v 1.32 2006/08/27 16:55:41 miod Exp $ */
/* $NetBSD: locore.c,v 1.43 2000/03/26 11:39:45 ragge Exp $ */
/*
* Copyright (c) 1994, 1998 Ludd, University of Lule}, Sweden.
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed at Ludd, University of Lule}.
* 4. 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.
*/
/* All bugs are subject to removal without further notice */
#include <sys/param.h>
#include <sys/reboot.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <sys/user.h>
#include <uvm/uvm_extern.h>
#include <machine/cpu.h>
#include <machine/sid.h>
#include <machine/param.h>
#include <machine/vmparam.h>
#include <machine/pcb.h>
#include <machine/pte.h>
#include <machine/pmap.h>
#include <machine/nexus.h>
#include <machine/rpb.h>
void start(struct rpb *);
void main(void);
extern paddr_t avail_end;
paddr_t esym;
u_int proc0paddr;
char cpu_model[100];
/*
* The strict cpu-dependent information is set up here, in
* form of a pointer to a struct that is specific for each cpu.
*/
extern struct cpu_dep ka780_calls;
extern struct cpu_dep ka750_calls;
extern struct cpu_dep ka860_calls;
extern struct cpu_dep ka820_calls;
extern struct cpu_dep ka43_calls;
extern struct cpu_dep ka46_calls;
extern struct cpu_dep ka48_calls;
extern struct cpu_dep ka49_calls;
extern struct cpu_dep ka53_calls;
extern struct cpu_dep ka410_calls;
extern struct cpu_dep ka630_calls;
extern struct cpu_dep ka650_calls;
extern struct cpu_dep ka660_calls;
extern struct cpu_dep ka670_calls;
extern struct cpu_dep ka680_calls;
extern struct cpu_dep vxt_calls;
/*
* Start is called from boot; the first routine that is called
* in kernel. Kernel stack is setup somewhere in a safe place;
* but we need to move it to a better known place. Memory
* management is disabled, and no interrupt system is active.
*/
void
start(struct rpb *prpb)
{
extern void *scratch;
mtpr(AST_NO, PR_ASTLVL); /* Turn off ASTs */
findcpu(); /* Set up the CPU identifying variables */
if (vax_confdata & 0x80)
strlcpy(cpu_model, "MicroVAX ", sizeof cpu_model);
else
strlcpy(cpu_model, "VAXstation ", sizeof cpu_model);
switch (vax_boardtype) {
#if VAX780
case VAX_BTYP_780:
dep_call = &ka780_calls;
strlcpy(cpu_model,"VAX 11/780", sizeof cpu_model);
if (vax_cpudata & 0x100)
cpu_model[9] = '5';
break;
#endif
#if VAX750
case VAX_BTYP_750:
dep_call = &ka750_calls;
strlcpy(cpu_model, "VAX 11/750", sizeof cpu_model);
break;
#endif
#if VAX8600
case VAX_BTYP_790:
dep_call = &ka860_calls;
strlcpy(cpu_model,"VAX 8600", sizeof cpu_model);
if (vax_cpudata & 0x100)
cpu_model[6] = '5';
break;
#endif
#if VAX410
case VAX_BTYP_420: /* They are very similar */
dep_call = &ka410_calls;
strlcat(cpu_model, "3100", sizeof cpu_model);
switch ((vax_siedata >> 8) & 0xff) {
case 0x00:
strlcat(cpu_model, "/m{30,40}", sizeof cpu_model);
break;
case 0x01:
strlcat(cpu_model, "/m{38,48}", sizeof cpu_model);
break;
case 0x02:
strlcat(cpu_model, "/m{10,20}{,e}", sizeof cpu_model);
break;
}
break;
case VAX_BTYP_410:
dep_call = &ka410_calls;
strlcat(cpu_model, "2000", sizeof cpu_model);
break;
#endif
#if VAX43
case VAX_BTYP_43:
dep_call = &ka43_calls;
strlcat(cpu_model, "3100/m76", sizeof cpu_model);
break;
#endif
#if VAX46
case VAX_BTYP_46:
dep_call = &ka46_calls;
switch(vax_siedata & 0xff) {
case VAX_VTYP_47:
strlcpy(cpu_model, "MicroVAX 3100 m80", sizeof cpu_model);
break;
case VAX_VTYP_46:
strlcpy(cpu_model, "VAXstation 4000/60", sizeof cpu_model);
break;
default:
strlcat(cpu_model, " - Unknown Mariah", sizeof cpu_model);
}
break;
#endif
#ifdef VXT
case VAX_BTYP_VXT:
dep_call = &vxt_calls;
strlcpy(cpu_model, "VXT2000", sizeof cpu_model);
break;
#endif
#if VAX48
case VAX_BTYP_48:
dep_call = &ka48_calls;
switch ((vax_siedata >> 8) & 0xff) {
case VAX_STYP_45:
strlcpy(cpu_model, "MicroVAX 3100/m{30,40}", sizeof cpu_model);
break;
case VAX_STYP_48:
strlcpy(cpu_model, "VAXstation 4000/VLC", sizeof cpu_model);
break;
default:
strlcat(cpu_model, " - Unknown SOC", sizeof cpu_model);
}
break;
#endif
#if VAX49
case VAX_BTYP_49:
dep_call = &ka49_calls;
strlcpy(cpu_model, "VAXstation 4000/90", sizeof cpu_model);
break;
#endif
#if VAX53
case VAX_BTYP_1303:
dep_call = &ka53_calls;
switch ((vax_siedata >> 8) & 0xff) {
case VAX_STYP_50:
strlcpy(cpu_model, "MicroVAX 3100 model 85 or 90", sizeof cpu_model);
break;
case VAX_STYP_51:
strlcpy(cpu_model, "MicroVAX 3100 model 90 or 95", sizeof cpu_model);
break;
case VAX_STYP_52:
strlcpy(cpu_model, "VAX 4000 100", sizeof cpu_model);
break;
case VAX_STYP_53:
strlcpy(cpu_model, "VAX 4000 105A", sizeof cpu_model);
break;
default:
strlcpy(cpu_model, "VAX - Unknown Cheetah Class", sizeof cpu_model);
}
break;
#endif
#if VAX630
case VAX_BTYP_630:
dep_call = &ka630_calls;
strlcpy(cpu_model,"MicroVAX II", sizeof cpu_model);
break;
#endif
#if VAX650
case VAX_BTYP_650:
dep_call = &ka650_calls;
strlcpy(cpu_model,"MicroVAX ", sizeof cpu_model);
switch ((vax_siedata >> 8) & 255) {
case VAX_SIE_KA640:
strlcat(cpu_model, "3300/3400", sizeof cpu_model);
break;
case VAX_SIE_KA650:
strlcat(cpu_model, "3500/3600", sizeof cpu_model);
break;
case VAX_SIE_KA655:
strlcat(cpu_model, "3800/3900", sizeof cpu_model);
break;
default:
strlcat(cpu_model, "III", sizeof cpu_model);
break;
}
break;
#endif
#if VAX660
case VAX_BTYP_660:
dep_call = &ka660_calls;
strlcpy(cpu_model,"VAX 4000 200", sizeof cpu_model);
break;
#endif
#if VAX670
case VAX_BTYP_670:
dep_call = &ka670_calls;
strlcpy(cpu_model,"VAX 4000 300", sizeof cpu_model);
break;
#endif
#if VAX680
case VAX_BTYP_1301:
dep_call = &ka680_calls;
strlcpy(cpu_model,"VAX 4000 ", sizeof cpu_model);
switch ((vax_siedata >> 8) & 0xff) {
case VAX_STYP_675:
strlcat(cpu_model,"400", sizeof cpu_model);
break;
case VAX_STYP_680:
strlcat(cpu_model,"500", sizeof cpu_model);
break;
case VAX_STYP_690:
strlcat(cpu_model,"600", sizeof cpu_model);
break;
default:
strlcat(cpu_model,"- Unknown Omega Class", sizeof cpu_model);
}
break;
case VAX_BTYP_1305:
dep_call = &ka680_calls;
strlcpy(cpu_model,"VAX 4000 ", sizeof cpu_model);
switch ((vax_siedata >> 8) & 0xff) {
case VAX_STYP_681:
strlcat(cpu_model,"500A", sizeof cpu_model);
break;
case VAX_STYP_691:
strlcat(cpu_model,"605A", sizeof cpu_model);
break;
case VAX_STYP_694:
if (vax_cpudata & 0x1000)
strlcat(cpu_model,"705A", sizeof cpu_model);
else
strlcat(cpu_model,"700A", sizeof cpu_model);
break;
default:
strlcat(cpu_model,"- Unknown Legacy Class", sizeof cpu_model);
}
break;
#endif
#if VAX8200
case VAX_BTYP_8000:
mastercpu = mfpr(PR_BINID);
dep_call = &ka820_calls;
strlcpy(cpu_model, "VAX 8200", sizeof cpu_model);
break;
#endif
default:
/* CPU not supported, just give up */
asm("halt");
}
/*
* Machines older than MicroVAX II have their boot blocks
* loaded directly or the boot program loaded from console
* media, so we need to figure out their memory size.
* This is not easily done on MicroVAXen, so we get it from
* VMB instead.
*
* In post-1.4 a RPB is always provided from the boot blocks.
*/
#if 1 /* compat with old bootblocks */
if (prpb == 0) {
bzero((caddr_t)proc0paddr + REDZONEADDR, sizeof(struct rpb));
prpb = (struct rpb *)(proc0paddr + REDZONEADDR);
prpb->pfncnt = avail_end >> VAX_PGSHIFT;
prpb->rpb_base = (void *)-1; /* RPB is fake */
} else
#endif
bcopy(prpb, (caddr_t)proc0paddr + REDZONEADDR, sizeof(struct rpb));
if (prpb->pfncnt)
avail_end = prpb->pfncnt << VAX_PGSHIFT;
else
while (badaddr((caddr_t)avail_end, 4) == 0)
avail_end += VAX_NBPG * 128;
boothowto = prpb->rpb_bootr5;
avail_end = TRUNC_PAGE(avail_end); /* be sure */
proc0.p_addr = (struct user *)proc0paddr; /* XXX */
bzero((struct user *)proc0paddr, sizeof(struct user));
/* Clear the used parts of the uarea except for the pcb */
bzero(&proc0.p_addr->u_stats, sizeof(struct user) - sizeof(struct pcb));
pmap_bootstrap();
/* Now running virtual. set red zone for proc0 */
*kvtopte((u_int)proc0.p_addr + REDZONEADDR) &= ~PG_V;
((struct pcb *)proc0paddr)->framep = scratch;
/*
* Change mode down to userspace is done by faking a stack
* frame that is setup in cpu_set_kpc(). Not done by returning
* from main anymore.
*/
main();
/* NOTREACHED */
}