1192067Snwhitehorn/*-
2236098Sraj * Copyright (c) 2008-2012 Semihalf.
3192067Snwhitehorn * All rights reserved.
4192067Snwhitehorn *
5192067Snwhitehorn * Redistribution and use in source and binary forms, with or without
6192067Snwhitehorn * modification, are permitted provided that the following conditions
7192067Snwhitehorn * are met:
8192067Snwhitehorn *
9192067Snwhitehorn * 1. Redistributions of source code must retain the above copyright
10192067Snwhitehorn *    notice, this list of conditions and the following disclaimer.
11192067Snwhitehorn * 2. Redistributions in binary form must reproduce the above copyright
12192067Snwhitehorn *    notice, this list of conditions and the following disclaimer in the
13192067Snwhitehorn *    documentation and/or other materials provided with the distribution.
14192067Snwhitehorn *
15192067Snwhitehorn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16192067Snwhitehorn * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17192067Snwhitehorn * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18192067Snwhitehorn * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19192067Snwhitehorn * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20192067Snwhitehorn * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21192067Snwhitehorn * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22192067Snwhitehorn * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23192067Snwhitehorn * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24192067Snwhitehorn * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25192067Snwhitehorn */
26192067Snwhitehorn
27192067Snwhitehorn#include <sys/cdefs.h>
28192067Snwhitehorn__FBSDID("$FreeBSD$");
29192067Snwhitehorn
30192067Snwhitehorn#include <sys/param.h>
31192067Snwhitehorn#include <sys/systm.h>
32192067Snwhitehorn#include <sys/kernel.h>
33192067Snwhitehorn#include <sys/bus.h>
34192067Snwhitehorn#include <sys/pcpu.h>
35192067Snwhitehorn#include <sys/proc.h>
36192067Snwhitehorn#include <sys/smp.h>
37192067Snwhitehorn
38257995Snwhitehorn#include <dev/ofw/openfirm.h>
39257995Snwhitehorn
40192067Snwhitehorn#include <machine/platform.h>
41192067Snwhitehorn#include <machine/platformvar.h>
42192067Snwhitehorn
43192067Snwhitehorn#include "platform_if.h"
44192067Snwhitehorn
45217523Smarcelextern uint32_t *bootinfo;
46217523Smarcel
47192067Snwhitehornstatic int bare_probe(platform_t);
48258807Snwhitehornstatic void bare_mem_regions(platform_t, struct mem_region *phys, int *physsz,
49258807Snwhitehorn    struct mem_region *avail, int *availsz);
50192067Snwhitehornstatic u_long bare_timebase_freq(platform_t, struct cpuref *cpuref);
51192067Snwhitehorn
52257995Snwhitehornstatic void bare_reset(platform_t);
53212054Snwhitehorn
54192067Snwhitehornstatic platform_method_t bare_methods[] = {
55236325Sraj	PLATFORMMETHOD(platform_probe,		bare_probe),
56192067Snwhitehorn	PLATFORMMETHOD(platform_mem_regions,	bare_mem_regions),
57192067Snwhitehorn	PLATFORMMETHOD(platform_timebase_freq,	bare_timebase_freq),
58192067Snwhitehorn
59257995Snwhitehorn	PLATFORMMETHOD(platform_reset,		bare_reset),
60192067Snwhitehorn
61246732Srpaulo	PLATFORMMETHOD_END
62192067Snwhitehorn};
63192067Snwhitehorn
64192067Snwhitehornstatic platform_def_t bare_platform = {
65257995Snwhitehorn	"bare",
66192067Snwhitehorn	bare_methods,
67192067Snwhitehorn	0
68192067Snwhitehorn};
69192067Snwhitehorn
70192067SnwhitehornPLATFORM_DEF(bare_platform);
71192067Snwhitehorn
72192067Snwhitehornstatic int
73192067Snwhitehornbare_probe(platform_t plat)
74192067Snwhitehorn{
75192067Snwhitehorn
76257995Snwhitehorn	if (OF_peer(0) == -1) /* Needs device tree to work */
77257995Snwhitehorn		return (ENXIO);
78193492Sraj
79192067Snwhitehorn	return (BUS_PROBE_GENERIC);
80192067Snwhitehorn}
81192067Snwhitehorn
82192067Snwhitehornvoid
83258807Snwhitehornbare_mem_regions(platform_t plat, struct mem_region *phys, int *physsz,
84258807Snwhitehorn    struct mem_region *avail, int *availsz)
85192067Snwhitehorn{
86192067Snwhitehorn
87257995Snwhitehorn	ofw_mem_regions(phys, physsz, avail, availsz);
88192067Snwhitehorn}
89192067Snwhitehorn
90192067Snwhitehornstatic u_long
91192067Snwhitehornbare_timebase_freq(platform_t plat, struct cpuref *cpuref)
92192067Snwhitehorn{
93217523Smarcel	u_long ticks;
94209908Sraj	phandle_t cpus, child;
95209908Sraj	pcell_t freq;
96192067Snwhitehorn
97224618Smarcel	if (bootinfo != NULL) {
98224611Smarcel		if (bootinfo[0] == 1) {
99224611Smarcel			/* Backward compatibility. See 8-STABLE. */
100224611Smarcel			ticks = bootinfo[3] >> 3;
101224611Smarcel		} else {
102224618Smarcel			/* Compatibility with Juniper's loader. */
103224611Smarcel			ticks = bootinfo[5] >> 3;
104224618Smarcel		}
105222327Smarcel	} else
106222327Smarcel		ticks = 0;
107217523Smarcel
108228201Sjchandra	if ((cpus = OF_finddevice("/cpus")) == -1)
109209908Sraj		goto out;
110209908Sraj
111209908Sraj	if ((child = OF_child(cpus)) == 0)
112209908Sraj		goto out;
113209908Sraj
114256974Snwhitehorn	switch (OF_getproplen(child, "timebase-frequency")) {
115256974Snwhitehorn	case 4:
116256974Snwhitehorn	{
117256974Snwhitehorn		uint32_t tbase;
118256974Snwhitehorn		OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase));
119256974Snwhitehorn		ticks = tbase;
120256974Snwhitehorn		return (ticks);
121256974Snwhitehorn	}
122256974Snwhitehorn	case 8:
123256974Snwhitehorn	{
124256974Snwhitehorn		uint64_t tbase;
125256974Snwhitehorn		OF_getprop(child, "timebase-frequency", &tbase, sizeof(tbase));
126256974Snwhitehorn		ticks = tbase;
127256974Snwhitehorn		return (ticks);
128256974Snwhitehorn	}
129256974Snwhitehorn	default:
130256974Snwhitehorn		break;
131256974Snwhitehorn	}
132256973Snwhitehorn
133217523Smarcel	freq = 0;
134209908Sraj	if (OF_getprop(child, "bus-frequency", (void *)&freq,
135209908Sraj	    sizeof(freq)) <= 0)
136209908Sraj		goto out;
137217523Smarcel
138192067Snwhitehorn	/*
139192067Snwhitehorn	 * Time Base and Decrementer are updated every 8 CCB bus clocks.
140192067Snwhitehorn	 * HID0[SEL_TBCLK] = 0
141192067Snwhitehorn	 */
142217523Smarcel	if (freq != 0)
143217523Smarcel		ticks = freq / 8;
144217523Smarcel
145209908Srajout:
146192067Snwhitehorn	if (ticks <= 0)
147192067Snwhitehorn		panic("Unable to determine timebase frequency!");
148192067Snwhitehorn
149192067Snwhitehorn	return (ticks);
150192067Snwhitehorn}
151192067Snwhitehorn
152212054Snwhitehornstatic void
153257995Snwhitehornbare_reset(platform_t plat)
154212054Snwhitehorn{
155212054Snwhitehorn
156212054Snwhitehorn	printf("Reset failed...\n");
157236097Sraj	while (1)
158236097Sraj		;
159212054Snwhitehorn}
160212054Snwhitehorn
161