File: [local] / sys / arch / mvmeppc / dev / cpu.c (download)
Revision 1.1.1.1 (vendor branch), Tue Mar 4 16:07:44 2008 UTC (16 years, 6 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: cpu.c,v 1.8 2004/11/18 16:10:28 miod Exp $ */
/*
* Copyright (c) 1997 Per Fogelstrom
* Copyright (c) 1997 RTMX Inc
*
* 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 under OpenBSD for RTMX Inc
* North Carolina, USA, by Per Fogelstrom, Opsycon AB, Sweden.
* 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.
*
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/device.h>
#include <machine/autoconf.h>
/* only valid on 603(e,ev) and G3, G4 */
#define HID0_DOZE (1 << (31-8))
#define HID0_NAP (1 << (31-9))
#define HID0_SLEEP (1 << (31-10))
#define HID0_DPM (1 << (31-11))
#define HID0_SGE (1 << (31-24))
#define HID0_BTIC (1 << (31-26))
#define HID0_LRSTK (1 << (31-27))
#define HID0_FOLD (1 << (31-28))
#define HID0_BHT (1 << (31-29))
char cpu_model[80];
char machine[] = MACHINE; /* cpu architecture */
/* Definition of the driver for autoconfig. */
int cpumatch(struct device *, void *, void *);
void cpuattach(struct device *, struct device *, void *);
struct cfattach cpu_ca = {
sizeof(struct device), cpumatch, cpuattach
};
struct cfdriver cpu_cd = {
NULL, "cpu", DV_DULL
};
void config_l2cr(int cpu);
int
cpumatch(parent, cfdata, aux)
struct device *parent;
void *cfdata;
void *aux;
{
struct confargs *ca = aux;
/* make sure that we're looking for a CPU. */
if (strcmp(ca->ca_name, cpu_cd.cd_name) != 0)
return (0);
return (1);
}
void
cpuattach(struct device *parent, struct device *dev, void *aux)
{
unsigned int cpu, pvr, hid0;
pvr = ppc_mfpvr();
cpu = pvr >> 16;
switch (cpu) {
case PPC_CPU_MPC601:
snprintf(cpu_model, sizeof(cpu_model), "601");
break;
case PPC_CPU_MPC603:
snprintf(cpu_model, sizeof(cpu_model), "603");
break;
case PPC_CPU_MPC604:
snprintf(cpu_model, sizeof(cpu_model), "604");
break;
case PPC_CPU_MPC603e:
snprintf(cpu_model, sizeof(cpu_model), "603e");
break;
case PPC_CPU_MPC603ev:
snprintf(cpu_model, sizeof(cpu_model), "603ev");
break;
case PPC_CPU_MPC750:
snprintf(cpu_model, sizeof(cpu_model), "750");
break;
case PPC_CPU_MPC604ev:
snprintf(cpu_model, sizeof(cpu_model), "604ev");
break;
case PPC_CPU_MPC7400:
snprintf(cpu_model, sizeof(cpu_model), "7400");
break;
case PPC_CPU_IBM750FX:
snprintf(cpu_model, sizeof(cpu_model), "750FX");
break;
case PPC_CPU_MPC7410:
snprintf(cpu_model, sizeof(cpu_model), "7410");
break;
case PPC_CPU_MPC7450:
if ((pvr & 0xf) < 3)
snprintf(cpu_model, sizeof(cpu_model), "7450");
else
snprintf(cpu_model, sizeof(cpu_model), "7451");
break;
case PPC_CPU_MPC7455:
snprintf(cpu_model, sizeof(cpu_model), "7455");
break;
default:
snprintf(cpu_model, sizeof(cpu_model), "Version %x", cpu);
break;
}
snprintf(cpu_model + strlen(cpu_model),
sizeof(cpu_model) - strlen(cpu_model),
" (Revision %x)", pvr & 0xffff);
printf(": %s", cpu_model);
/* power savings mode */
hid0 = ppc_mfhid0();
switch (cpu) {
case PPC_CPU_MPC603:
case PPC_CPU_MPC603e:
case PPC_CPU_MPC750:
case PPC_CPU_MPC7400:
case PPC_CPU_IBM750FX:
case PPC_CPU_MPC7410:
/* select DOZE mode */
hid0 &= ~(HID0_NAP | HID0_SLEEP);
hid0 |= HID0_DOZE | HID0_DPM;
break;
case PPC_CPU_MPC7450:
case PPC_CPU_MPC7455:
/* select NAP mode */
hid0 &= ~(HID0_DOZE | HID0_SLEEP);
hid0 |= HID0_NAP | HID0_DPM;
/* try some other flags */
hid0 |= HID0_SGE | HID0_BTIC;
hid0 |= HID0_LRSTK | HID0_FOLD | HID0_BHT;
/* Disable BTIC on 7450 Rev 2.0 or earlier */
if (cpu == PPC_CPU_MPC7450 && (pvr & 0xffff) < 0x0200)
hid0 &= ~HID0_BTIC;
break;
}
ppc_mthid0(hid0);
/* if processor is G3 or G4, configure l2 cache */
if (cpu == PPC_CPU_MPC750 || cpu == PPC_CPU_MPC7400 ||
cpu == PPC_CPU_IBM750FX || cpu == PPC_CPU_MPC7410 ||
cpu == PPC_CPU_MPC7450 || cpu == PPC_CPU_MPC7455) {
config_l2cr(cpu);
}
printf("\n");
}
/* L2CR bit definitions */
#define L2CR_L2E 0x80000000 /* 0: L2 enable */
#define L2CR_L2PE 0x40000000 /* 1: L2 data parity enable */
#define L2CR_L2SIZ 0x30000000 /* 2-3: L2 size */
#define L2SIZ_RESERVED 0x00000000
#define L2SIZ_256K 0x10000000
#define L2SIZ_512K 0x20000000
#define L2SIZ_1M 0x30000000
#define L2CR_L2CLK 0x0e000000 /* 4-6: L2 clock ratio */
#define L2CLK_DIS 0x00000000 /* disable L2 clock */
#define L2CLK_10 0x02000000 /* core clock / 1 */
#define L2CLK_15 0x04000000 /* / 1.5 */
#define L2CLK_20 0x08000000 /* / 2 */
#define L2CLK_25 0x0a000000 /* / 2.5 */
#define L2CLK_30 0x0c000000 /* / 3 */
#define L2CR_L2RAM 0x01800000 /* 7-8: L2 RAM type */
#define L2RAM_FLOWTHRU_BURST 0x00000000
#define L2RAM_PIPELINE_BURST 0x01000000
#define L2RAM_PIPELINE_LATE 0x01800000
#define L2CR_L2DO 0x00400000 /* 9: L2 data-only.
Setting this bit disables instruction
caching. */
#define L2CR_L2I 0x00200000 /* 10: L2 global invalidate. */
#define L2CR_L2CTL 0x00100000 /* 11: L2 RAM control (ZZ enable).
Enables automatic operation of the
L2ZZ (low-power mode) signal. */
#define L2CR_L2WT 0x00080000 /* 12: L2 write-through. */
#define L2CR_L2TS 0x00040000 /* 13: L2 test support. */
#define L2CR_L2OH 0x00030000 /* 14-15: L2 output hold. */
#define L2CR_L2SL 0x00008000 /* 16: L2 DLL slow. */
#define L2CR_L2DF 0x00004000 /* 17: L2 differential clock. */
#define L2CR_L2BYP 0x00002000 /* 18: L2 DLL bypass. */
#define L2CR_L2IP 0x00000001 /* 31: L2 global invalidate in progress
(read only). */
#ifdef L2CR_CONFIG
u_int l2cr_config = L2CR_CONFIG;
#else
u_int l2cr_config = 0;
#endif
/* L3CR bit definitions */
#define L3CR_L3E 0x80000000 /* 0: L3 enable */
#define L3CR_L3SIZ 0x10000000 /* 3: L3 size (0=1MB, 1=2MB) */
void
config_l2cr(int cpu)
{
u_int l2cr, x;
l2cr = ppc_mfl2cr();
/*
* Configure L2 cache if not enabled.
*/
if ((l2cr & L2CR_L2E) == 0 && l2cr_config != 0) {
l2cr = l2cr_config;
ppc_mtl2cr(l2cr);
/* Wait for L2 clock to be stable (640 L2 clocks). */
delay(100);
/* Invalidate all L2 contents. */
l2cr |= L2CR_L2I;
ppc_mtl2cr(l2cr);
do {
x = ppc_mfl2cr();
} while (x & L2CR_L2IP);
/* Enable L2 cache. */
l2cr &= ~L2CR_L2I;
l2cr |= L2CR_L2E;
ppc_mtl2cr(l2cr);
}
if (l2cr & L2CR_L2E) {
if (cpu == PPC_CPU_MPC7450 || cpu == PPC_CPU_MPC7455) {
u_int l3cr;
printf(": 256KB L2 cache");
l3cr = ppc_mfl3cr();
if (l3cr & L3CR_L3E)
printf(", %cMB L3 cache",
l3cr & L3CR_L3SIZ ? '2' : '1');
} else if (cpu == PPC_CPU_IBM750FX)
printf(": 512KB L2 cache");
else {
switch (l2cr & L2CR_L2SIZ) {
case L2SIZ_256K:
printf(": 256KB");
break;
case L2SIZ_512K:
printf(": 512KB");
break;
case L2SIZ_1M:
printf(": 1MB");
break;
default:
printf(": unknown size");
}
printf(" backside cache");
}
#if 0
switch (l2cr & L2CR_L2RAM) {
case L2RAM_FLOWTHRU_BURST:
printf(" Flow-through synchronous burst SRAM");
break;
case L2RAM_PIPELINE_BURST:
printf(" Pipelined synchronous burst SRAM");
break;
case L2RAM_PIPELINE_LATE:
printf(" Pipelined synchronous late-write SRAM");
break;
default:
printf(" unknown type");
}
if (l2cr & L2CR_L2PE)
printf(" with parity");
#endif
} else
printf(": L2 cache not enabled");
}