Various changes to use the firmware on a real machine.
This commit is contained in:
parent
940bcd77bd
commit
cf1a145b08
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=84128
@ -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 @@ calibrate_clocks(u_int32_t firmware_freq)
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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,9 +566,39 @@ 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.
|
||||
*/
|
||||
@ -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));
|
||||
@ -668,26 +799,6 @@ ia64_init()
|
||||
mtx_init(&proc0.p_mtx, "process lock", MTX_DEF);
|
||||
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.
|
||||
*/
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user