Age | Commit message (Collapse) | Author |
|
This makes vmap()/vunmap() take a vlong size argument,
and change the type of Pci.mem[].size to vlong as well.
Even if vmap() wont support large mappings, it is nice to
get the original unruncated value for error checking.
pc64 needs a bigger VMAP window, as system76 pangolin
puts the framebuffer at a physical address > 512GB.
|
|
|
|
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).
|
|
|
|
|
|
|
|
|
|
Use the MTRR registers to exclude memory ranges that
do not have the expected cache attributes:
RAM -> writeback
UMB -> uncached
UPA -> uncached
|
|
This implements proper intrdisable() support for all
interrupt controllers.
For enable, (*arch->intrassign)(Vctl*) fills in the
Vctl.enable and Vctl.disable pointers with the
appropriate routines and returns the assigned
vector number.
Once the Vctl struct has been linked to its vector
chain, Vctl.enable(Vctl*, shared) gets called with a
flag if the vector has been already enabled (shared).
This order is important here as enabling the interrupt
on the controller before we have linked the chain can
cause spurious interrupts, expecially on mp system
where the interrupt can target a different cpu than
the caller of intrenable().
The intrdisable() case is the other way around.
We first disable the interrupt on the controller
and after that unlink the Vctl from the chain.
On a multiprocessor, the xfree() of the Vctl struct
is delayed to avoid freeing it while it is still
in use by another cpu.
The xen port now also uses pc/irq.c which has been
made generic enougth to handle xen's irq scheme.
Also, archgeneric is now a separate file to avoid
pulling in dependencies from the 8259 interrupt
controller code.
|
|
port/iomap.c
With some newer UEFI firmware, not all pci bars get
programmed and we have to assign them ourselfs.
This was already done for memory bars. This change
adds the same for i/o port space, by providing a
ioreservewin() function which can be used to allocate
port space within the parent pci-pci bridge window.
Also, the pci code now allocates the pci config
space i/o ports 0xCF8/0xCFC so userspace needs to
use devpnp to access pci config space now. (see
latest realemu change).
Also, this moves the ioalloc()/iofree() code out
of devarch into port/iomap.c as it can be shared
with the ppc mtx kernel.
|
|
The new pci code is moved to port/pci.[hc] and shared by
all ports.
Each port has its own PCI controller implementation,
providing the pcicfgrw*() functions for low level pci
config space access. The locking for pcicfgrw*() is now
done by the caller (only port/pci.c).
Device drivers now need to include "../port/pci.h" in
addition to "io.h".
The new code now checks bridge windows and membars,
while enumerating the bus, giving the pc driver a chance
to re-assign them. This is needed because some UEFI
implementations fail to assign the bars for some devices,
so we need to do it outselfs. (See pcireservemem()).
While working on this, it was discovered that the pci
code assimed the smallest I/O bar size is 16 (pcibarsize()),
which is wrong. I/O bars can be as small as 4 bytes.
Bit 1 in an I/O bar is also reserved and should be masked off,
making the port mask: port = bar & ~3;
|
|
|
|
|
|
This replaces the memory map code for both pc and pc64
kernels with a unified implementation using the new
portable memory map code.
The main motivation is to be robust against broken
e820 memory maps by the bios and delay the Conf.mem[]
allocation after archinit(), so mp and acpi tables
can be reserved and excluded from user memory.
There are a few changes:
new memreserve() function has been added for archinit()
to reserve bios and acpi tables.
upareserve() has been replaced by upaalloc(), which now
has an address argument.
umbrwmalloc() and umbmalloc() have been replaced by
umballoc().
both upaalloc() and umballoc() return physical addresses
or -1 on error. the physical address -1 is now used as
a sentinel value instead of 0 when dealing with physical
addresses.
archmp and archacpi now always use vmap() to access
the bios tables and reserve the ranges. more overflow
checks have been added.
ramscan() has been rewritten using vmap().
to handle the population of kernel memory, pc and pc64
now have pmap() and punmap() functions to do permanent
mappings.
|
|
for device drivers
|
|
pcienable() puts a device in fully powered on state
and does some missing initialization that UEFI might
have skipped such as I/O and Memory requests being
disabled.
pcidisable() is ment to shutdown the device, but
currently just disables dma to prevent accidents.
|
|
nobody passes us the "RSD PTR " address when doing multiboot/kexec
on UEFI systems. so we search for it manually in the ACPI reserved
area as indicated in the e820 memory map.
|
|
|
|
specific fpu handling
introducing the PFPU structue which allows the machine specific
code some flexibility on how to handle the FPU process state.
for example, in the pc and pc64 kernel, the FPsave structure is
arround 512 bytes. with avx512, it could grow up to 2K. instead
of embedding that into the Proc strucutre, it is more effective
to allocate it on first use of the fpu, as most processes do not
use simd or floating point in the first place. also, the FPsave
structure has special 16 byte alignment constraint, which further
favours dynamic allocation.
this gets rid of the memmoves in pc/pc64 kernels for the aligment.
there is also devproc, which is now checking if the fpsave area
is actually valid before reading it, avoiding debuggers to see
garbage data.
the Notsave structure is gone now, as it was not used on any
machine.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
on some modern machines like the x250, the bios arranges the mtrr's
and the framebuffer membar in a way that doesnt allow us to mark
the framebuffer pages as write combining, leading to slow graphics.
since the pentium III, the processor interprets the page table bit
combinations of the WT, CD and bit7 bits as an index into the
page attribute table (PAT).
to not change the semantics of the WT and CD bits, we preserve
the bit patterns 0-3 and use the last entry 7 for write combining.
(done in mmuinit() for each core).
the new patwc() function takes virtual address range and changes
the page table marking the range as write combining. no attempt
is made on invalidating tlb's. doesnt matter in our case as the
following mtrr() call in screen.c does it for us.
|
|
|
|
the psaux driver is not used in any kernel configuration and theres
no userspace mouse daemon. i8042auxcmds() is wrong as access
to the user buffer can fault and we are holding an ilocks.
little cleanups in devkbd.
|
|
remove kbdenable()/kbdinit()
on vmware, loading a new kernel sometimes reboots when
wiggling the mouse. disabling keyboard and mouse on
shutdown fixes the issue.
make sure ps2 mouse is disabled on init, will get re-enabled
in i8042auxenable().
keyboard isnt special anymore, we can just use the devreset
entry point in the device to do the keyboard initialization,
so kbdinit()/kbdenable() are not needed anymore.
|
|
intrdisable() will always be able to unregister the interrupt
now, so there is no reason to have it return an error value.
all drivers except uart8250 already assumed it to never fail
and theres no need to maintain that complexity.
|
|
mpshutdown() used to call acpireset() making it impossible to build
a kernel without archacpi. now, mpshutdown() is a helper function
that only shuts down the application processors that gets used from
mpreset() and acpireset().
the generic machine reset code in exported by devarch's archreset()
function that is called by mpreset() and from acpireset() as a fallback.
so the code duplication that was in mpshutdown() is avoided.
|
|
|
|
x230 booted in efi only (no csp) mode hangs
when traditional i8042reset() keyboard reset
is tried.
so we try acpireset() first which discoveres
and writes the acpi reset register.
|
|
to make it possible to mark the bootscreen framebuffer
as write combining in early initialization, mtrr() is
changed not not to error() but to return an error string.
as bootscreen() is used before multiprocessor initialization,
we have to synchronize the mtrr's for every processor as
it comes online. for this, a new mtrrsync() function is
provided that is called from cpuidentify() if mtrr support
is indicated.
the boot processor runs mtrrsync() which snarfs the
registers. later, mtrrsync() is run again from the
application processors which apply the values from the
boot processor.
checkmtrr() from mp.c was removed as its task is also
done by mtrrsync() now.
|
|
|
|
|
|
|
|
new format
we now always use the new FXSAVE format in FPsave structure and fpregs
file, converting back and forth in fpx87save() and fpx87restore().
document that fprestore() is a destructive operation now.
change fp register definition in libmach and adapt fpr() acid funciton.
avoid unneccesary copy of fpstate and fpsave in sysfork(). functions
including syscalls do not preserve the fp registers and copying fpstate
from the current process would mean we had to fpsave(&up->fpsave); first.
simply not doing it, new process starts in FPinit state.
|
|
|
|
|
|
access to non standard serial port COM3 at i/o port 0x200 causes
kernel panic on some machines (Toshiba Sattelite 1415-S115). also,
some machines have gameport at 0x200.
i readded uartisa to the pcf and pccpuf kernel configurations so
one can use plan9.ini to add non standard uarts like:
uart2=type=isa port=0x200 irq=5
|
|
the syscallno check in syscallfmt() was wrong. the unsigned
syscall number was cast to an signed integer. so negative
values would pass the check provoking bad memory access from
kernel. the check also has an off by one. one has to check
syscallno >= nsyscalls instead of syscallno > nsyscalls.
access to the p->syscalltrace string was not protected
from modification in devproc. you could awake the process
and cause it to free the string giving an opportunity for
the kernel to access bad memory. or someone could kill the
process (pexit would just free it).
now the string is protected by the usual p->debug qlock. we
also keep the string arround until it is overwritten again
or the process exists. this has the nice side effect that
one can inspect it after the process crashed.
another problem was that our validaddr() would error() instead
of pexiting the current process. the code was changed to only
access up->s.args after it was validated and copied instead of
accessing the user stack directly. this also prevents a sneaky
multithreaded process from chaning the arguments under us.
in case our validaddr() errors, we cannot assume valid user
stack after the waserror() if block. use up->s.arg[0] for the
noted() call to avoid bad access.
|
|
use fastclock timer (pit2) to measure cpufreq in guesscpuhz(). this
gives a bigger period minimizing the danger of overrun as pit2 runs
at the constant maximum period of 0x10000 ticks. also use smaller
loop increments (1000) and bigger maximum loop upper bound.
move the loops < ... check to the bottom of the loop so we get the
effective count *before* adding the next loop increment.
ilock() while doing measurements in guesscpuhz() to prevent accidents
with other processors reading fastclock or doing guesscpuhz()
in parralel.
export new i8253reset() function for apm to reset the timers after
a apm bios suspend.
|
|
|
|
replace the various functions that searched for bios data structures by
a single sigsearch() one in pc/memory.c that will probe the various bios
data areas.
also, a new checksum() function was added that is to be used to validate
the structures found.
|
|
|
|
|
|
|
|
|