aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDoug Rabson <dfr@FreeBSD.org>2001-09-29 11:43:37 +0000
committerDoug Rabson <dfr@FreeBSD.org>2001-09-29 11:43:37 +0000
commitcf1a145b08848d89b6fb218d7db5b0482ea499c5 (patch)
treeabada069220d1f8ee10b06e166fdaa5755c58ea4 /sys
parent940bcd77bdff2623342d6225143bc51904d9f8a7 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/ia64/ia64/clock.c17
-rw-r--r--sys/ia64/ia64/machdep.c195
2 files changed, 166 insertions, 46 deletions
diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c
index fc3ad07f9f168..3bc8aced77171 100644
--- a/sys/ia64/ia64/clock.c
+++ b/sys/ia64/ia64/clock.c
@@ -53,6 +53,8 @@
#include <sys/bus.h>
#include <sys/timetc.h>
+#include <machine/pal.h>
+#include <machine/sal.h>
#include <machine/clock.h>
#include <machine/clockvar.h>
#include <isa/isareg.h>
@@ -78,7 +80,7 @@ int disable_rtc_set; /* disable resettodr() if != 0 */
int wall_cmos_clock; /* wall CMOS clock assumed if != 0 */
static int beeping = 0;
-extern int cycles_per_sec;
+extern u_char itc_frequency;
static timecounter_get_t ia64_get_timecount;
@@ -129,7 +131,6 @@ clockattach(device_t dev)
if (clockdev)
panic("clockattach: multiple clocks");
clockdev = dev;
- cycles_per_sec = calibrate_clocks(cycles_per_sec);
#ifdef EVCNT_COUNTERS
evcnt_attach(dev, "intr", &clock_intr_evcnt);
#endif
@@ -176,12 +177,10 @@ cpu_initclocks()
tickfixinterval = hz >> (ftp - 1);
}
- /*
- * XXX we should call SAL_FREQ_BASE_INTERVAL_TIMER here.
- */
- cycles_per_sec = 70000000;
+ if (!itc_frequency)
+ panic("Unknown clock frequency");
- freq = cycles_per_sec;
+ freq = itc_frequency;
last_time = ia64_get_itc();
scaled_ticks_per_cycle = ((u_int64_t)hz << FIX_SHIFT) / freq;
max_cycles_per_tick = 2*freq / hz;
@@ -189,7 +188,7 @@ cpu_initclocks()
ia64_timecounter.tc_frequency = freq;
tc_init(&ia64_timecounter);
- ia64_set_itm(ia64_get_itc() + (cycles_per_sec + hz/2) / hz);
+ ia64_set_itm(ia64_get_itc() + (itc_frequency + hz/2) / hz);
ia64_set_itv(240); /* highest priority class */
stathz = 128;
@@ -252,7 +251,7 @@ fail:
void
handleclock(void* arg)
{
- ia64_set_itm(ia64_get_itc() + (cycles_per_sec + hz/2) / hz);
+ ia64_set_itm(ia64_get_itc() + (itc_frequency + hz/2) / hz);
hardclock(arg);
}
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index c0a699aabb2b5..7bcde7c03422f 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000 Doug Rabson
+ * Copyright (c) 2000,2001 Doug Rabson
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -28,7 +28,7 @@
#include "opt_compat.h"
#include "opt_ddb.h"
-#include "opt_simos.h"
+#include "opt_ski.h"
#include "opt_msgbuf.h"
#include <sys/param.h>
@@ -68,6 +68,7 @@
#include <machine/reg.h>
#include <machine/fpu.h>
#include <machine/pal.h>
+#include <machine/sal.h>
#include <machine/bootinfo.h>
#include <machine/mutex.h>
#include <machine/vmparam.h>
@@ -77,15 +78,15 @@
#include <sys/vnode.h>
#include <fs/procfs/procfs.h>
#include <machine/sigframe.h>
+#include <machine/efi.h>
-#include <boot/efi/include/ia64/efibind.h>
-#include <boot/efi/include/efidef.h>
-#include <boot/efi/include/efidevp.h>
-#include <boot/efi/include/eficon.h>
-#include <boot/efi/include/efiapi.h>
+#ifdef SKI
+extern void ia64_ski_init(void);
+#endif
-u_int64_t cycles_per_usec;
-u_int32_t cycles_per_sec;
+u_int64_t processor_frequency;
+u_int64_t bus_frequency;
+u_int64_t itc_frequency;
int cold = 1;
struct bootinfo bootinfo;
@@ -382,7 +383,13 @@ identifycpu(void)
features = ia64_get_cpuid(4);
- printf("CPU: %s\n", familyname);
+ printf("CPU: %s", familyname);
+ if (processor_frequency)
+ printf(" (%ld.%02ld-Mhz)\n",
+ (processor_frequency + 4999) / 1000000,
+ ((processor_frequency + 4999) / 10000) % 100);
+ else
+ printf("\n");
printf(" Origin = \"%s\" Model = %d Revision = %d\n",
vendor, model, revision);
printf(" Features = 0x%b\n", (u_int32_t) features,
@@ -392,8 +399,99 @@ identifycpu(void)
extern char kernel_text[], _end[];
+static void
+map_pal_code(void)
+{
+ EFI_MEMORY_DESCRIPTOR *md, *mdp;
+ int mdcount, i;
+ u_int64_t psr;
+ struct ia64_pte pte;
+ vm_offset_t addr;
+
+ if (!bootinfo.bi_systab)
+ return;
+
+ mdcount = bootinfo.bi_memmap_size / bootinfo.bi_memdesc_size;
+ md = (EFI_MEMORY_DESCRIPTOR *) IA64_PHYS_TO_RR7(bootinfo.bi_memmap);
+
+ for (i = 0, mdp = md; i < mdcount; i++,
+ mdp = NextMemoryDescriptor(mdp, bootinfo.bi_memdesc_size)) {
+ if (mdp->Type == EfiPalCode)
+ break;
+ }
+
+ if (i == mdcount) {
+ printf("Can't find PAL Code\n");
+ return;
+ }
+
+ /*
+ * We use a TR to map the first 256M of memory - this might
+ * cover the palcode too.
+ */
+ if ((mdp->PhysicalStart & ~((1 << 28) - 1)) == 0) {
+ printf("PAL Code is mapped by the kernel's TR\n");
+ return;
+ }
+
+ addr = mdp->PhysicalStart & ~((1 << 28) - 1);
+
+ bzero(&pte, sizeof(pte));
+ pte.pte_p = 1;
+ pte.pte_ma = PTE_MA_WB;
+ pte.pte_a = 1;
+ pte.pte_d = 1;
+ pte.pte_pl = PTE_PL_KERN;
+ pte.pte_ar = PTE_AR_RWX;
+ pte.pte_ppn = addr >> 12;
+
+ __asm __volatile("mov %0=psr;;" : "=r" (psr));
+ __asm __volatile("rsm psr.ic|psr.i;; srlz.i;;");
+ __asm __volatile("mov cr.ifa=%0" :: "r"(IA64_PHYS_TO_RR7(addr)));
+ __asm __volatile("mov cr.itir=%0" :: "r"(28 << 2));
+ __asm __volatile("srlz.i;;");
+ __asm __volatile("itr.i itr[%0]=%1;;"
+ :: "r"(2), "r"(*(u_int64_t*)&pte));
+ __asm __volatile("srlz.i;;");
+ __asm __volatile("mov psr.l=%0;; srlz.i" :: "r" (psr));
+}
+
+static void
+calculate_frequencies(void)
+{
+ struct ia64_sal_result sal;
+ struct ia64_pal_result pal;
+
+ sal = ia64_sal_entry(SAL_FREQ_BASE, 0, 0, 0, 0, 0, 0, 0);
+ pal = ia64_call_pal_static(PAL_FREQ_RATIOS, 0, 0, 0);
+
+ if (sal.sal_status == 0 && pal.pal_status == 0) {
+ if (bootverbose) {
+ printf("Platform clock frequency %ld Hz\n",
+ sal.sal_result[0]);
+ printf("Processor ratio %ld/%ld, Bus ratio %ld/%ld, "
+ "ITC ratio %ld/%ld\n",
+ pal.pal_result[0] >> 32,
+ pal.pal_result[0] & ((1L << 32) - 1),
+ pal.pal_result[1] >> 32,
+ pal.pal_result[1] & ((1L << 32) - 1),
+ pal.pal_result[2] >> 32,
+ pal.pal_result[2] & ((1L << 32) - 1));
+ }
+ processor_frequency =
+ sal.sal_result[0] * (pal.pal_result[0] >> 32)
+ / (pal.pal_result[0] & ((1L << 32) - 1));
+ bus_frequency =
+ sal.sal_result[0] * (pal.pal_result[1] >> 32)
+ / (pal.pal_result[1] & ((1L << 32) - 1));
+ itc_frequency =
+ sal.sal_result[0] * (pal.pal_result[2] >> 32)
+ / (pal.pal_result[2] & ((1L << 32) - 1));
+ }
+}
+
void
-ia64_init()
+ia64_init(u_int64_t arg1, u_int64_t arg2)
{
int phys_avail_cnt;
vm_offset_t kernstart, kernend;
@@ -433,6 +531,7 @@ ia64_init()
mdcount = bootinfo.bi_memmap_size / bootinfo.bi_memdesc_size;
md = (EFI_MEMORY_DESCRIPTOR *) IA64_PHYS_TO_RR7(bootinfo.bi_memmap);
if (!md) {
+#ifdef SKI
static EFI_MEMORY_DESCRIPTOR ski_md[2];
/*
* XXX hack for ski. In reality, the loader will probably ask
@@ -453,6 +552,7 @@ ia64_init()
md = ski_md;
mdcount = 2;
+#endif
}
for (i = 0, mdp = md; i < mdcount; i++,
@@ -466,10 +566,40 @@ ia64_init()
* Initialize the console before we print anything out.
*/
cninit();
-
+
/* OUTPUT NOW ALLOWED */
/*
+ * Look at arguments passed to us and compute boothowto.
+ */
+ boothowto = bootinfo.bi_boothowto;
+#ifdef KADB
+ boothowto |= RB_KDB;
+#endif
+
+ /*
+ * Catch case of boot_verbose set in environment.
+ */
+ if ((p = getenv("boot_verbose")) != NULL) {
+ if (strcmp(p, "yes") == 0 || strcmp(p, "YES") == 0) {
+ boothowto |= RB_VERBOSE;
+ }
+ }
+
+ if (boothowto & RB_VERBOSE)
+ bootverbose = 1;
+
+ /*
+ * Wire things up so we can call the firmware.
+ */
+ map_pal_code();
+ ia64_efi_init();
+#ifdef SKI
+ ia64_ski_init();
+#endif
+ calculate_frequencies();
+
+ /*
* Find the beginning and end of the kernel.
*/
kernstart = trunc_page(kernel_text);
@@ -517,6 +647,7 @@ ia64_init()
mdp->PhysicalStart,
mdp->NumberOfPages);
#endif
+
pfn0 = ia64_btop(round_page(mdp->PhysicalStart));
pfn1 = ia64_btop(trunc_page(mdp->PhysicalStart
+ mdp->NumberOfPages * 4096));
@@ -669,26 +800,6 @@ ia64_init()
mtx_lock(&Giant);
/*
- * Look at arguments passed to us and compute boothowto.
- */
- boothowto = bootinfo.bi_boothowto;
-#ifdef KADB
- boothowto |= RB_KDB;
-#endif
-
- /*
- * Catch case of boot_verbose set in environment.
- */
- if ((p = getenv("boot_verbose")) != NULL) {
- if (strcmp(p, "yes") == 0 || strcmp(p, "YES") == 0) {
- boothowto |= RB_VERBOSE;
- }
- }
-
- if (boothowto & RB_VERBOSE)
- bootverbose = 1;
-
- /*
* Force single-user for a while.
*/
boothowto |= RB_SINGLE;
@@ -746,7 +857,17 @@ bzero(void *buf, size_t len)
void
DELAY(int n)
{
- /* TODO */
+ u_int64_t start, end, now;
+
+ /*
+ * XXX This can't cope with rollovers.
+ */
+ start = ia64_get_itc();
+ end = start + (itc_frequency * n) / 1000000;
+ /* printf("DELAY from 0x%lx to 0x%lx\n", start, end); */
+ do {
+ now = ia64_get_itc();
+ } while (now < end);
}
/*
@@ -1044,13 +1165,12 @@ sigreturn(struct thread *td,
/*
* Machine dependent boot() routine
- *
- * I haven't seen anything to put here yet
- * Possibly some stuff might be grafted back here from boot()
*/
void
cpu_boot(int howto)
{
+
+ ia64_efi_runtime->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, 0);
}
/*
@@ -1059,7 +1179,8 @@ cpu_boot(int howto)
void
cpu_halt(void)
{
- /* TODO */
+
+ ia64_efi_runtime->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, 0);
}
/*