Tilting allows using left/right rotated or invetrted display orientation.
This can be changed at runtime such as: echo tilt right > /dev/vgactl
This removes the old panning and vga overlays as they are only implemented
with some ancient vga controllers.
Previously, mmurelease() was always called with
palloc spinlock held.
This is unneccesary for some mmurelease()
implementations as they wont release pages
to the palloc pool.
This change removes pagechainhead() and
pagechaindone() and replaces them with just
freepages() call, which aquires the palloc
lock internally as needed.
freepages() avoids holding the palloc lock
while walking the linked list of pages,
avoding some lock contention.
we might as well handle the per process cycle
counter in the portable part instead of duplicating the code
in every arch and have inconsistent implementations.
we now have a portable kenter() and kexit() function,
that is ment to be used in trap/syscall from user,
which updates the counters.
some kernels missed initializing Mach.cyclefreq.
the tulip driver is used in microsofts hypver-v
as the legacy ethernet adapter for pxe booting.
to make the driver work on pc64, we need to
store the Block* pointers in a separate array
instead of stuffing them into buffer address 2
of the hardware descriptor.
also, enable the driver in the pc64 kernel.
enable pci busmaster before set the fis-receive-enable
bit in the port command register.
not doing so triggers a crash in qemu like:
address_space_unmap: Assertion `mr != NULL' failed.
as qemu tries to process the dma command list as soon
as we set that flag and busmaster dma needs to be enabled
at this point.
Bhyve returns 0 in MTRRCap register, so we
can use that instead on relying on cpuid only
to see if MTRR's are supported.
That way we can get rid of the sanity check
in memory.c.
On AMD64, CR0/CR4 are 64-bit registers, with
the upper half reserved. So use uintptr type
to store the register values to get 32 bit on 386
and 64 bit on AMD64.
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.
It appears that our IDT overlaps with the data structures
passed from grub in multiboot load.
So defer setup of the interrupt table after the multiboot
parameters have been processed.
The driver used to register the interrupt handler just
after reset, tho the Ctlr struct, including the buffer
descriptor arrays where only allocated on attach.
This moves most of the reset/init out of pnp
function and into attach. This also means we can
error out and even retry on the next attach.
The logic of the reseter kproc has been changed:
now it is only started once the first initialization
completely succeeded. This avoids the strange qlock
passing.
Implement a shutdown function so the device gets
halted for /dev/reboot.
Assume 64 bit physical addresses for dma.
Check that pci bar0 is actually I/O.
The new MTRR code handles overlapping ranges
and supports AMD specific TOM2 MSR.
The format in /dev/archctl now only shows
the effective cache ranges only, without
exposing the low level registers.
loading the interrupt vector table early allows
us to handle traps during bootup before mmuinit()
which gives better diagnostics for debugging.
we also can handle general protection fault on
rdmsr() and wrmsr() which helps during
cpuidentify() and archinit() when probing for
cpu features.
before removing the double map at 0, load our
initial gdt pointer with its new KZERO based
virtual address.
this is prerequisite for handling traps early during
bootup before mmuinit() loads the final gdt.
When using /dev/reboot, the MSI vecor might have already
been setup causing interrupts to fire on the designated
cpu while we send the commands to the card.
reseting irbsts bits in hdacmd() only works
while interrupts are disabled during hdareset().
once interrupts are enabled we need to reset the
irbsts bits in the interrupt handler or else the
interrupt never clears and locks up the system.
The change 3306:c5cf77167bfe made the code reuse MTRR slots
of the default memory type.
But this did not take overlapping ranges into account!
If two or more variable-range MTRRs overlap, the following rules apply:
a. If the memory types are identical, then that memory type is used.
b. If at least one of the memory types is UC, then UC memory type is used.
c. If at least of of the memory types is WT. and the only other memory type
is WB, then th WT memory type is used.
d. If the combination of memory types is not listed above,
then the memory type used in undefined.
It so happend that on a Dell Latitude E7450 that the BIOS defines
the default type as UC. and the first slot defines a 16GB range
of type WB. Then the rest of the ranges mark the PCI space back
as UC, but overlapping the first WB range! This works because
of rule (B) above.
When trying to make the framebuffer write-combining, we would
falsely reuse one of the UC sub-ranges and making the UC memory
into WB as a side effect.
Thanks to Fulton for his patience and providing debug logs and
doing experiments for us to narrow the problem down.
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 driver was not using irb interrupts
and was just polling the irb write pointer
to wait for command completion.
this is not supported by qemu.
qemu requires the use of irb interrupt handshake
and it refuses to accept the next command until we
acknowledge the irb interrupt.
the access functions for pci config space in config mode #1
used to set bit 0 in the register offset if the access was
to a device on any bus different from 0.
it is completely unclear why this was done and i can't find
any documentation on this.
but for sure, this breaks all pci config spacess access to
pci devices behind a bridge on qemu. with -trace pci* it
was discovered that all config space register offsets on
devies behind pci brige where off by one.
on real hardware, setting bit 0 in the offset doesnt appear
to be an issue.
thanks mischief for reporting and providing a qemu demo
configuration to reproduce the problem.
On my 6235 card, if we calibrate the crystal
immediately after disabling wimax, the the
firmware gets unhappy. A short nap before
sending the command prevents the command from
timing out.
ori and echoline are reporting regression on some 6000 cards;
which sometimes time out on crystal calibration command;
which is expected by the driver. but the new code used
to force a device reset on any command timeout.
reverting to old behaviour until for now until we have
a chance investigating.
We used to assume a 1:1 pairing of processors to submit queues.
With recent machines, we now got more cpu cores than what some
nvme drives support so we need to distribute the queues across
these cpu's which requires locking on command submission.
There is a feature get/set command to probe the number of submit
and completion queues, but we decided to just handling
submission queue create command error gracefully as it is simpler
and has less chance of regression with existing setups.
Thanks to mischief for investigating and writing the code.
the 9000 series uses a new receive descriptor format
wich appears to reqire 4k aligned buffers. the old
format "halfworks" and just makes the firmware not
respond to any commands after the enable paging command.
the smartfifo command appears to causes problems.
but apparently not issuing it at all seems to work
fine on both the 8265 and 9260. so removing the code
for now.
issuing the bindingquota command before associated
makes association impossible. but enabling afterwards
works fine. (tested in 8265 and 9260).
the prph access functions now mask the address with
0xfffff. it is unclear why linux and openbsd drivers
specify addresses beyond that in ther register constants.
the timeevent change is interesting. the timeevent
needs to be restarted when it has stoped to make sure
probing/association packets are sent during the evnet.
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;
the page attribute table was initialized in mmuinit(), which is
too late for bootscreen(). So now we check for PAT support and
insert the write-combine entry early in cpuidentify().
this might have been the cause of some slow EFI framebuffers on
machines with overlapping or insufficient MTRR entries.
The swcursor used a 32x32 image for saving/restoring
screen contents for no reason.
Add a doflush argument to swcursorhide(), so that
disabling software cursor with a double buffered
softscreen is properly hidden. The doflush parameter
should be set to 0 in all other cases as swcursordraw()
will flushes both (current and previours) locations.
Make sure swcursorinit() and swcursorhide() clear the
visibility flag, even when gscreen is nil.
Remove the cursor locking and just do everything within
the drawlock. All cursor functions such as curson(),
cursoff() and setcursor() will be called drawlock
locked. This also means &cursor can be read.
Fix devmouse cursor reads and writes. We now have the
global cursor variable that is only modified under
the drawlock. So copy under drawlock.
Move the pc software cursor implementation into vgasoft
driver, so screen.c does not need to handle it as
a special case.
Remove unused functions such as drawhasclients().
most pc's are multiprocessors these days, that use apic or
msi interrupts, then the irq does not matter anymore. and
uefi does not even assign irq to pci devices anymore. if
we have a problem enabling an interrupt, we will print.
memory returned by rampage() is not zeroed, so we have to
zero it ourselfs. apparently, this bug didnt show up as we
where zeroing conventional low memory before the new memory
map code. also rampage() never returns nil.
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.
Fix the inconsistent use of ether->mem. Always use physical
addresses. Let ether8390 convert to virtual addresses using
KADDR() when we have to copy data in/out.
the previous mkfile had a sneaky hack that would use
sed to delete the first 2 lines of hex output to strip
the 32 byte long a.out header for apbootstrap and rebootcode.
use 8l -H3 flag to strip the header from the output file.
replace machine specific userinit() by a portable
implemntation that uses kproc() to create the first
process. the initcode text is mapped using kmap(),
so there is no need for machine specific tmpmap()
functions.
initcode stack preparation should be done in init0()
where the stack is mapped and can be accessed directly.
replacing the machine specific userinit() allows some
big simplifications as sysrfork() and kproc() are now
the only callers of newproc() and we can avoid initializing
fields that we know are being initialized by these
callers.
rename autogenerated init.h and reboot.h headers.
the initcode[] and rebootcode[] blobs are now in *.i
files and hex generation was moved to portmkfile. the
machine specific mkfile only needs to specify how to
build rebootcode.out and initcode.out.
comparing m with MACHP() is wrong as m is a constant on 386.
add procflushothers(), which flushes all processes except up
using common procflushmmu() routine.
when a process does an exec syscall, procsetup() is called and
we have to disable the debug watchpoint registers. just clearing
p->dr is not enougth as we are not going thru a procsave() and
procrestore() cycle which would disable and reload the saved
debug registers.
instead of clearing debug registers in procfork(), we should
clear the saved debug registers before a process goes to die
(pexit() calls sched() with up->state = Moribund) as the Proc
structure can get reused for kernel processes (kproc) which
never call procfork() and would therefore have debug registers
loaded.