plan9fox/sys/src/9/pc/archgeneric.c
cinap_lenrek a05bab362f pc, pc64: add minimal HPET driver to measure LAPIC and TSC frequencies
This adds the new function pointer PCArch.clockinit(),
which is a timer dependent initialization routine.
It also takes over the job of guesscpuhz(). This way, the
architecture ident code can switch between different
timers (i8253, HPET and XEN timer).
2021-01-17 21:21:12 +01:00

96 lines
1.8 KiB
C

#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "ureg.h"
#include "../port/error.h"
extern int i8259assign(Vctl*);
extern int i8259irqno(int, int);
extern void i8259init(void);
extern int i8259isr(int);
extern void i8259on(void);
extern void i8259off(void);
extern int i8259vecno(int);
void
archreset(void)
{
i8042reset();
/*
* Often the BIOS hangs during restart if a conventional 8042
* warm-boot sequence is tried. The following is Intel specific and
* seems to perform a cold-boot, but at least it comes back.
* And sometimes there is no keyboard...
*
* The reset register (0xcf9) is usually in one of the bridge
* chips. The actual location and sequence could be extracted from
* ACPI but why bother, this is the end of the line anyway.
*/
print("Takes a licking and keeps on ticking...\n");
*(ushort*)KADDR(0x472) = 0x1234; /* BIOS warm-boot flag */
outb(0xcf9, 0x02);
outb(0xcf9, 0x06);
print("can't reset\n");
for(;;)
idle();
}
void
delay(int millisecs)
{
millisecs *= m->loopconst;
if(millisecs <= 0)
millisecs = 1;
aamloop(millisecs);
}
void
microdelay(int microsecs)
{
microsecs *= m->loopconst;
microsecs /= 1000;
if(microsecs <= 0)
microsecs = 1;
aamloop(microsecs);
}
/*
* performance measurement ticks. must be low overhead.
* doesn't have to count over a second.
*/
ulong
perfticks(void)
{
uvlong x;
if(m->havetsc)
cycles(&x);
else
x = 0;
return x;
}
PCArch archgeneric = {
.id= "generic",
.ident= 0,
.reset= archreset,
.intrinit= i8259init,
.intrassign= i8259assign,
.intrirqno= i8259irqno,
.intrvecno= i8259vecno,
.intrspurious= i8259isr,
.intron= i8259on,
.introff= i8259off,
.clockinit= i8253init,
.clockenable= i8253enable,
.fastclock= i8253read,
.timerset= i8253timerset,
};