add support for edp, dp and hdmi on haswell and haswell ult.
vga, dvi and specific configurations like ulx are unimplemented.
remaining issue: edp link training always fails (time out).
turns out on real hardware, the front falls off if we write
the completion queue doorbell registers without consuming
an entry. so only write the register when we have processed
something.
basic NVMe controller driver, reads and writes work.
"namespaces" show up as logical units.
uses pin/msi interrupts (no msi-x support yet).
one submission queue per cpu, shared completion queue.
no recovery from fatal controller errors.
only tested in qemu (no hardware available).
commiting this so it can be found by someone who has
hardware.
on thinkpad x1v4, the PCMP structure resides in upper reserved memory
pa=0xd7f49000 - while system memory ends at 0x0ffff000; so we have to
vmap() it instead of KADDR().
the RSD structure for ACPI might reside in low memory, so we sould
KADDR() in that case.
devmouse controls the screen blanking timeout, so move the
code there avoiding cross calls between modules. the only
function that needs to be provided is blankscreen(), which
gets called with drawlock locked.
the blank timeout is set thru /dev/mousectl now, so kernels
without devvga can set it.
blanking now only happens while /dev/mouse is read. so this
avoids accidentally blanking the screen on cpu servers that
do not have a mouse to unblank it.
- add some milisecond timestamps to the status change debug printing
- flush the packets in the queue on deassoc to avoid processing old pae
packets on next association.
- make roaming timeout shorter (60 -> 20 seconds)
- automatically timeout and restart wpa/pae blocked state
- fix printing race when essid gets changed underneath seprint
from openbsd driver, it seems the Centrino Advanced-N 6030 and 6235
cards share the same device revision as the 6205 (Type6005). Also
changing the device revision field from 4 to 5 bits.
- drivers enable short preamble and sort timeslot depending
on the ap beacon capinfo field (bss->cap)
- wifi sets short preamble bit in capinfo on association request
- wifi sets short timeslot bit when ap advertized it in beacon
given that the igfx driver doesnt provide any acceleration functions
and drawing is usually faster with double buffering as it eleminates
reads over the pci bus, enable softscreen by default.
on 386 kernel, each processor has its own pdb where the primary
pdb for kernel mappings is on cpu0 and other cpu's lazily pull
pdb entries from cpu0 when they fault in vmapsync().
so we have to edit the table tables in the pdb of cpu0 and not
the current processor.
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.
get rid of _INI and _REG method calls, this is not full acpi environment
anyway and all we really want todo at kernel boot time is figuring out
the interrupt routing. aux/acpi can try to enable more stuff if it needs
to later when battery status desired.
dont snoop memory space regions in amlmapio(), this is just wrong as
amlmapio() is *lazily* mapping regions as they are accessed, so the
range table would never be really complete. instead, we provide generic
access to the physical address space, excluding kernel and user memory
with acpimem file.
the first time rtl8169link is called (from rtl8169pnp), the link isn't up, so
setting edev->mbps based on Phystatus register is skipped. edev->mbps is then
still set at the default 100, and that ends up being what devether uses.
this is why some rtl8169 cards are misprinted as 100Mbps in kmesg.
later, after rtl8169link is called again from rtl8169interrupt, the link is up
and edev->mbps is set to the correct value (as shown by e.g. /net/ether0/stats).
so instead, set speed regardless of link status.
This patch is only an adaptation for 9front of the patch located in
http://www.9legacy.org/9legacy/patch/pc-ether82563-i210.diff. The
major difference is that this patch ignores errors in checksum of
eeprom, because in my system the checksum was wrong. After 3 months,
I didn't have problems, and I think the patch can be used. although
it has some things that need to be fixed. If the link is inactive
when the system boots then it will remain inactive forever.
access to the axi segment hangs the machine when the fpga
is not programmed yet. to prevent access, we introduce a
new SG_FAULT flag, that when set on the Segment.type or
Physseg.attr, causes the fault handler to immidiately
return with an error (as if the segment would not be mapped).
during programming, we temporarily set the SG_FAULT flag
on the axi physseg, flush all processes tlb's that have
the segment mapped and when programming is done, we clear
the flag again.
this code was if(0) for a long time due to wrong parentesis,
fixed parentesis cause print spam on some machines making them
unusage (kenji okomoto). removing the check alltogether.
apparently, this causes some quadcore ramnode vm to hang on boot,
even tho all cores successfully started up and are operational.
i suspect some side effect from timersinit()... this would also
mean *notsc= would break it (syncclock() would continue)...
its unclear.
i'm reverting this for now until the problem is better understood.
when testing in qemu, launching each ap became slower and slower
because all the ap's where spinning in syncclock() waiting for
cpu0 to update its mach0->tscticks, which happens only much later
after all cpu's have been started up.
now we wait for each cpu to do its timer callibration and
manually update our tscticks while we wait and each cpu will
not spin but halt while waiting for active.thunderbirdsarego.
this reduces the system load and noise for timer callibration
and makes the mp startup linear with regard to the number of
cores.
introduce cpushutdown() function that does the common
operation of initiating shutdown, returning once all
cpu's got the message and are about to shutdown. this
avoids duplicated code which isnt really machine specific.
automatic reboot on panic only when *debug= is not set
and the machine is a cpu server or has no display,
otherwise just hang.
introduce wificfg() function to convert ether->opt[] strings
to wifictl messages, which needs quoting for the value. so
etherX=type=iwl essid='something with spaces' works.
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.
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.
the keyboard stops sending interrupts when its fifo gets full,
which can happen on boot when keys get mashed while interrupts
are still disabled. to work arround this, call the keyboard
interrupt handler when kbd.q is starved before blocking.
add bootscreenconf(VGAscr *) function, that is called whenever
the framebuffer configuration is changed by devvga. that way, we
can pass the current setting of the framebuffer to the new
kernel when using /dev/reboot.
Wnode gets two new counters: txcount and txerror
and actrate pointer that will be between minrate
and maxrate.
driver should use actrate instead of maxrate for
transmission when it can provide error feedback.
when a driver detects a transmission failed, it calls
wifitxfail() with the original packet. wifitxfail() then
reduces wn->actrate.
every 256th packet, we optimistically increase wn->actrate
before transmitting.
- reduce delay for channel hop to 200ms
- use 1000ms timeout for auth response (dont hop channels while we wait)
- bunny hop sequence is mathematically prooven
this avoids listing the upper half of 64-bit membars
in Pcidev.mem[] array avoiding potential confusion
in drivers.
we also check if the upper half is programmed to zero
by bios and otherwise zap the entry in Pcidev.mem[]
and print a warning.
qemu puts multiboot data after the end of the kernel image, so
to be able to KADDR() that memory early, we extend the initial
identity mapping by 16K. right now we just got lucky with
the pc kernel as it rounds the map to 4MB pages.
the following hooks have been added to the ehci Ctlr
structore to handle cache coherency (on arm):
void* (*tdalloc)(ulong,int,ulong);
void* (*dmaalloc)(ulong);
void (*dmafree)(void*);
void (*dmaflush)(int,void*,ulong);
tdalloc() is used to allocate descriptors and the periodic
frame schedule array. on arm, this needs to return uncached
memory. tdalloc()ed memory is never freed.
dmaalloc()/dmafree() is used for io buffers. this can return
cached memory when when hardware maintains cache coherency (pc)
or dmaflush() is provided to flush/invalidate the cache (zynq),
otherwise needs to return uncached memory.
dmaflush() is used to flush/invalidate the cache. the first
argument tells us if we need to flush (non zero) or
invalidate (zero).
uncached.h is gone now. this change makes the handling explicit.
there are no kernels currently that do page coloring,
so the only use of cachectl[] is flushing the icache
(on arm and ppc).
on pc64, cachectl consumes 32 bytes in each page resulting
in over 200 megabytes of overhead for 32gb of ram with 4K
pages.
this change removes cachectl[] and adds txtflush ulong
that is set to ~0 by pio() to instruct putmmu() to flush
the icache.
we used to read beyond the boundaries of the becon because of
the end pointer was offset by the beacon header. this is
also what caused the double entries.
the FPOFF macro that follows the FXSAVE/FSAVE instructions in l.s
used to execute WAIT instruction when the TS flag was not set. this
is wrong and causes pending exceptions to be raised from fpsave which
is called from provsave() which holds up->rlock making it deadlock
when matherror() tries to postnote() to itself.
so making FPOFF non-waiting (just set TS flag).
we handle pending exception when restoring the context.
initially, pio was used to access registers so i didnt need
a kernel driver for initial testing.
pio does not work under efi, so use mmio to access registers.
we have to reset hwblank when switching drivers to
prevent the generic vgablank() to be called by
blankscreen().
remove code setting hwblank from vga drivers as
devvga will always force hwblank to be 1 or 0
depending on if the driver provides a native blanking
routine.
set hwaccel to 1 when the driver provides native fill
and scroll routines independent of softscreen being
disabled. this allows hw acceleration to be used when
softscreen gets switched off.
don't hold drawlock duing vga enable and disable, but just zero
the function pointers under drawlock *before* disabling the vga
device.
holding the drawlock while calling out into enable and disable
is not a good idea. with vgavesa, this might deadlock when
userspace realemu tries to print in a rio window with vgavesa.
in 9front, screen blanking is always initiated from process context,
so there is no need for a kproc anymore.
care has been taken for the race between vesadisable() and vesablank()
by acquiering the drawlock prior calling scr->dev->enable() and
scr->dev->disable(). this also has the side effect of accelerated
fills and scrolls not being called during device disable.
At least on some NVIDIA cards the default scaling mode makes
black borders visible on all sides, even on native resolution.
This patch adds a generic "scaling MODE" command to vgactl
and adds support for it on VESA through NVIDIA VBE OEM extension.
It hasn't been tested on any other video cards, but shouldn't
break anything as the scaling mode is only set on write to vgactl.
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.
- shorten cpuidprnt so it doesnt have to break line
- addarchfile: complain when running out of entries
- fix range check in rmemrw() (harmless)
- use nil instead of 0 for pointers
there is no use for "bootdisk" variable parametrization
of /boot/boot and no point for the boot section with its
boot methods in the kernel configuration anymore. so
mkboot and boot$CONF.out are gone.
move the rules for bootfs.paq creation in 9/boot/bootmkfile.
location of bootfs.proto is now in 9/boot/bootfs.proto.
our /boot/boot target is now just "boot".
bug: Rnointerrupt was used on Vqueue.used.flags instead of
Vqueue.avail.flags.
introduce vqnotify() function that notifies the device
about available ring advancement.
avoid queue notifications there that can be slow by
checking Unonotify flag in Vqueue.used.flags.
keep track of the number of notifications in the queue.
- properly negotiate Fctrlrx feature bit for promisc and multicast.
- allow setting mac address with ea= option from plan9.ini
- dont read the isr register from ifstats() as it has the side effect of reseting isr status
- embedd the Vqueue array in the Ctlr structure avoiding indirection
- add a interrupt counter Vqueue.nintr for statistical purposes
- only read network status register if the feature has been negotiated
- change name to "virtio" as "ethervirtio" is kind of redundant
add vctlcmd() function to setup and comlete control commands.
handle Vctlq and implement promiscuous and multicast mode commands.
remove Vqueue.block[] and Vqueue.header. these are not properties
of the queue (Vctlq as no block array).
the block[] array only needs to be half the queue size as we use
two descriptors per packet.
fix broken shutdown() and remove useless ctl() function.
when we hit a conflict where the pci INTL register gives us
a different irq than we get from southbridge irq router, dont
just change the router setting to the bios assigned irq (that
was previously known as the BIOS workarround), but assume the
southbridge setting to be valid and change the pci INTL register
on the device to it.
only when the router link doesnt seem to be configured or
disabled, then program the router to the irq that bios asisgned
in the INTL register.
the reason is that changing the router setting changes the
irq routing for *all* devices on the same link and changing
it breaks previously checked and valid interrupt routings.
(so happend with virtualbox where the last device on the bus
is some powermanagement device that has wrong INTL setting
and changing the routing breaks the ethernet interrupts)
this change shouldnt affect modern machines which use ioapic
and mp tables or acpi for pci interrupt routing.
we add new function convmemsize() that returns the size of
*usable* conventional memory that does some sanity checking
and reserves the last KB below the top of memory pointer.
this avoids lowraminit() overriding potential bios tables
and sigsearch() going off the rails looking for tables
at above 640K.
Based on OpenBSD driver:
- /sys/dev/pci/azalia.c rev 1.209
- /sys/dev/pci/pcidevs rev 1.1689
- only tested on amd64; machine is an Acer V5-573G
exact model: V5-573G-74518G1Takk
vmware in efi mode brings application processors up
with CR4 = 0 (pse disabled) which makes us page fault
when accessing the ap's pdb which might be in a 4MB
mapping when the boot processor used pse to setup
page tables.
so we unconditionally enable pse in apbootstrap
(and disable pae in case of surprises).
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.
rampage() cannot be used after meminit(), so test for
conf.mem[0].npage != 0 and use xalloc()/mallocalign()
instead. this allows us to use vmap() early before
mmuinit() which is needed for bootscreeninit() and
acpi.
to get memory for page tables, pc64 needs a lowraminit().
with EFI, the RSDT pointer is passed in *acpi= parameter
from the efi loader. as the RSDT is ususally at the end of
the physical address space (and not to be found in
bios areas), we cannot KMAP() it so we need to vmap().
there was a memory corruption bug caused by us enabling the
ps2mouseputc() handler *before* initializing packetsize.
once we enabled the handler, mouse interrupts could come
in and advance the packet buffer index (nb) beyond the
buffer boundaries.
as ps2mouseputc() only checked for ++nb == packetsize, once
nb was advanced beyond the packetsize, it would continue writing
beyond the buffer and corrupt memory with each mouse packet byte.
solution is to initialize packetsize *before* enabling the
handler, and also do a >= check in ps2mouseputc() in case the
packetsize gets changed to a smaller value at runtime.
make the Page stucture less than half its original size by getting rid of
the Lock and the lru.
The Lock was required to coordinate the unchaining of pages that where
both cached and on the lru freelist.
now pages have a single next pointer that is used for palloc.head
freelist xor for page cache hash chains in Image.pghash[].
cached pages are not on the freelist anymore, but will be reclaimed
from images by the pager when the freelist runs out of pages.
each Image has its own 512 hash chains for cached page lookup. That is
2MB worth of pages and there should be no collisions for most text images.
page reclaiming can be done without holding palloc.lock as the Image is
the owner of the page hash chains protected by the Image's lock.
reclaiming Image structures can be done quickly by only reclaiming pages from
inactive images, that is images which are not currently in use by segments.
the Ref structure has no Lock anymore. Only a single long that is atomically
incremented or decremnted using cmpswap().
there are various other changes as a consequence code. and lots of pikeshedding,
sorry.
the vmware svga video card emulated by qemu (qemu -vga vmware) complains and eventually causes a panic if the rectangles aren't clipped.
messages like the following can be observed from qemu before the kernel panics:
vmsvga_update_rect: update h was < 0 (-20000)
vmsvga_update_rect: update height too large y: 10000, h: 0
vmsvga_update_rect: update w was < 0 (-20000)
vmsvga_update_rect: update width too large x: 10000, w: 0
i could only reproduce this in qemu 2.0.50 on the master branch, when using the ui and had selected 'Zoom To Fit' from the View menu.
fix bug introduced by amd64 support:
forgot to update ring index i on receive. surprisingly
this was working until there where more than one packet
to process. sorry.
ilock the controller while processing rings. this should
be fixed and use kprocs instead.
as with the Block refcount changes, _xinc() and _xdec() arent
used anymore, so remove them.
architecure can still define ainc()/adec() when it needs them.
as we do system reset and reboot only from boot processor cpu0 now,
theres no need for active.rebooting conditional variable.
mpshutdown() will unconditionally park application processors and
and cpu0 boots the new kernel or calls mpshutdown() causing system
reset.
in vmware, mpshutdown() used to hang in i8042reset() when not
called from the boot processor, so instead of reseting from first
cpu that acquires the shutdown lock, we park all application
processors and let the boot processor do the reset.
from the specification:
software may reset the entire HBA by setting GHC.HR to '1'.
When software sets the GHC.HR bit to '1', the HBA shall perform
an internal reset action. The bit shall be cleared to '0'
by the HBA when the reset is complete.
this was a big mistake. we should never attempt to
timeout or retry a scsi command from the controller
driver because theres no way to tell how long a
command would take or if a command has side effects
when being retried.
ftrvxmtrx repots devices that use the endpoint number for
input and output of different types like:
nusb/ether: parsedesc endpoint 5[7] 07 05 81 03 08 00 09 # ep1 in intr
nusb/ether: parsedesc endpoint 5[7] 07 05 82 02 00 02 00
nusb/ether: parsedesc endpoint 5[7] 07 05 01 02 00 02 00 # ep1 out bulk
the previous change tried to work arround this but had the
concequence that only the lastly defined endpoint was
usable.
this change addresses the issue by allowing up to 32 endpoints
per device (16 output + 16 input endpoints) in devusb. the
hci driver will ignore the 4th bit and will only use the
lower 4 bits as endpoint address when talking to the usb
device.
when we encounter a conflict, we map the input endpoint
to the upper id range 16..31 and the output endpoint
to id 0..15 so two distinct endpoints are created.
the 802.11 spec only specifies the msb of the rate for
Beacon, Probe Response, Association Response, Reassociation Response,
Mesh Peering Open, and Mesh Peering Confirm management frames
...
The MSB of each Supported Rate octet in other
management frame types is ignored by receiving STAs.
this should make no difference but on some netgear ap's not
setting this bit seems to ignore these data rates.
driver sets wifi->rates array to tell wifi layer what
rates it supports. when we receive beacon, we determine
the minimum and maximum data rates and set wn->minrate
and wn->maxrate to point to the entries in wifi->rates.
it is the responsibility of the driver to use this
information on transmit.
according to erik, virtualbox puts the source overrides
before the ioapic entries so the addirq() call fails
as no ioapics have been declared yet. use a second pass
over the table after we processed the apic entries.
do not store Block* pointer in packet descriptor, assumed
pointer would fit in a long. we use pointer table now to
record the Block* pointer and store index instead.
this change is in preparation for amd64. the systab calling
convention was also changed to return uintptr (as segattach
returns a pointer) and the arguments are now passed as
va_list which handles amd64 arguments properly (all arguments
are passed in 64bit quantities on the stack, tho the upper
part will not be initialized when the element is smaller
than 8 bytes).
this is partial. xalloc needs to be converted in the future.
according to a comment in linux driver, reading Isrc2
register caused interrupts to be disabled. we used
to read Isrc2 in ifstat() and it was confirmed that
reading ifstat locks up ethernet. removing the Isrc2
read in ifstats, and also reenable interrupts after
reading Isrc2 when the interrupt was not for us.
(this is from the linux driver)
in replenish(), set ring software write pointer (Sring.wp)
*before* the hardware write index register. otherwise
rx() could get status notification for completed
receive but wont find the rx descriptor in the ring.
handle uint wrap arround when calculating ring fill
count and remaining count.
disabling mouse packet streaming command 0xf5 can fail
when a packet is currently transmitted.
this can be seen when one moves the mouse while running:
while(){echo accelerated >/dev/mousectl; sleep 0.5}
dont spam the console with qfull warnings. this makes things worse.
handle loopback packets as stated in the comment. we call etheriq()
with fromwire=1 for loopback packets so etheriq() can pass the packet
on (without copying) or free it. dont inhibit interrupts while calling
etheriq(). etheriq() can safely be called from process and interrupt
context. it is unclear what this was supposed to fix and testing didnt
seem to have any odd effects.
catch the error() that can be thrown by sleep() and tsleep()
in kprocs.
add missing pexit() calls.
always set the freemem argument to pexit() from kproc otherwise
the process gets added to the broken list.