ref: 20ea113790c22e5fc8dd0051baa359e4fa083425
parent: add3a0a4da2f46f69a87782699e77c794a8b2cb9
author: cinap_lenrek <[email protected]>
date: Fri Nov 26 15:51:45 EST 2021
kernel: support large 64-bit pci membars, increase pc64 VMAPSIZE to 1TB 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.
--- a/sys/src/9/bcm64/fns.h
+++ b/sys/src/9/bcm64/fns.h
@@ -67,8 +67,8 @@
extern KMap *kmap(Page*);
extern void kunmap(KMap*);
extern uintptr mmukmap(uintptr, uintptr, usize);
-extern void* vmap(uvlong, int);
-extern void vunmap(void*, int);
+extern void* vmap(uvlong, vlong);
+extern void vunmap(void*, vlong);
extern void mmu0init(uintptr*);
extern void mmu0clear(uintptr*);
--- a/sys/src/9/bcm64/mmu.c
+++ b/sys/src/9/bcm64/mmu.c
@@ -324,7 +324,7 @@
}
void*
-vmap(uvlong pa, int size)
+vmap(uvlong pa, vlong size)
{
static uintptr base = VMAP;
uvlong pe = pa + size;
@@ -337,7 +337,7 @@
}
void
-vunmap(void *, int)
+vunmap(void *, vlong)
{
}
--- a/sys/src/9/pc/devpccard.c
+++ b/sys/src/9/pc/devpccard.c
@@ -1266,11 +1266,11 @@
for (i = 0; i < nelem(pci->mem); i++)
if (pci->mem[i].size)
p = seprint(p, e,
- "\tmem[%d] %.8ullX (%.8uX)\n",
+ "\tmem[%d] %.8ullX (%.8ullX)\n",
i, pci->mem[i].bar,
pci->mem[i].size);
if (pci->rom.size)
- p = seprint(p, e, "\tROM %.8ullX (%.8uX)\n",
+ p = seprint(p, e, "\tROM %.8ullX (%.8ullX)\n",
pci->rom.bar, pci->rom.size);
pci = pci->link;
}
--- a/sys/src/9/pc/etherwavelan.c
+++ b/sys/src/9/pc/etherwavelan.c
@@ -113,7 +113,7 @@
* On the Prism, bar[0] is the memory-mapped register address (4KB),
*/
if((p->mem[0].bar & 1) != 0 || p->mem[0].size != 4096){
- print("wavelanpci: %.4ux %.4ux: unlikely mmio bar %llux size %d\n",
+ print("wavelanpci: %.4ux %.4ux: unlikely mmio bar %llux size %lld\n",
p->vid, p->did, p->mem[0].bar, p->mem[0].size);
continue;
}
@@ -126,7 +126,7 @@
ctlr->pcidev = p;
mem = vmap(p->mem[0].bar&~0xF, p->mem[0].size);
if(mem == nil){
- print("wavelanpci: %.4ux %.4ux: vmap %llux %d failed\n",
+ print("wavelanpci: %.4ux %.4ux: vmap %llux %lld failed\n",
p->vid, p->did, p->mem[0].bar&~0xF, p->mem[0].size);
free(ctlr);
continue;
--- a/sys/src/9/pc/fns.h
+++ b/sys/src/9/pc/fns.h
@@ -159,15 +159,15 @@
uvlong tscticks(uvlong*);
ulong umballoc(ulong, ulong, ulong);
void umbfree(ulong, ulong);
-uvlong upaalloc(uvlong, ulong, ulong);
-uvlong upaallocwin(uvlong, ulong, ulong, ulong);
-void upafree(uvlong, ulong);
+uvlong upaalloc(uvlong, uvlong, uvlong);
+uvlong upaallocwin(uvlong, uvlong, uvlong, uvlong);
+void upafree(uvlong, uvlong);
void vectortable(void);
-void* vmap(uvlong, int);
+void* vmap(uvlong, vlong);
int vmapsync(ulong);
void vmxprocrestore(Proc *);
void vmxshutdown(void);
-void vunmap(void*, int);
+void vunmap(void*, vlong);
void wbinvd(void);
void writeconf(void);
int wrmsr(int, vlong);
--- a/sys/src/9/pc/memory.c
+++ b/sys/src/9/pc/memory.c
@@ -245,13 +245,13 @@
* Call vmap to do that.
*/
uvlong
-upaalloc(uvlong pa, ulong size, ulong align)
+upaalloc(uvlong pa, uvlong size, uvlong align)
{
return memmapalloc(pa, size, align, MemUPA);
}
uvlong
-upaallocwin(uvlong pa, ulong win, ulong size, ulong align)
+upaallocwin(uvlong pa, uvlong win, uvlong size, uvlong align)
{
uvlong a, base, top = pa + win;
@@ -269,7 +269,7 @@
}
void
-upafree(uvlong pa, ulong size)
+upafree(uvlong pa, uvlong size)
{
memmapfree(pa, size, MemUPA);
}
--- a/sys/src/9/pc/mmu.c
+++ b/sys/src/9/pc/mmu.c
@@ -530,13 +530,13 @@
* Add a device mapping to the vmap range.
*/
void*
-vmap(uvlong pa, int size)
+vmap(uvlong pa, vlong size)
{
- int osize;
+ vlong osize;
ulong o, va;
if(pa < BY2PG || size <= 0 || ((pa+size) >> 32) != 0 || size > VMAPSIZE){
- print("vmap pa=%llux size=%d pc=%#p\n", pa, size, getcallerpc(&pa));
+ print("vmap pa=%llux size=%lld pc=%#p\n", pa, size, getcallerpc(&pa));
return nil;
}
@@ -560,7 +560,7 @@
vmapsync(va+i);
*/
USED(osize);
-// print(" vmap %#.8lux %d => %#.8lux\n", pa+o, osize, va+o);
+// print(" vmap %#.8lux %lld => %#.8lux\n", pa+o, osize, va+o);
return (void*)(va + o);
}
@@ -621,7 +621,7 @@
* the call need not be interlocked with vmap.
*/
void
-vunmap(void *v, int size)
+vunmap(void *v, vlong size)
{
ulong va, o;
@@ -635,7 +635,7 @@
size = ROUND(size, BY2PG);
if(size < 0 || va < VMAP || va+size > VMAP+VMAPSIZE)
- panic("vunmap va=%#.8lux size=%#x pc=%#.8lux",
+ panic("vunmap va=%#.8lux size=%lld pc=%#.8lux",
va, size, getcallerpc(&v));
pdbunmap(MACHP(0)->pdb, va, size);
--- a/sys/src/9/pc/pcipc.c
+++ b/sys/src/9/pc/pcipc.c
@@ -603,7 +603,7 @@
p->mem[i].bar |= pa;
}
pcisetbar(p, PciBAR0 + i*4, p->mem[i].bar);
- DBG("%s: bar%d: fixed %.8lluX %d\n", tag, i, p->mem[i].bar, p->mem[i].size);
+ DBG("%s: bar%d: fixed %.8lluX %lld\n", tag, i, p->mem[i].bar, p->mem[i].size);
}
}
}
--- a/sys/src/9/pc/screen.c
+++ b/sys/src/9/pc/screen.c
@@ -563,9 +563,10 @@
}
static char*
-vgalinearaddr0(VGAscr *scr, uvlong paddr, int size)
+vgalinearaddr0(VGAscr *scr, uvlong paddr, vlong size)
{
- int x, nsize;
+ int x;
+ vlong nsize;
uvlong npaddr;
/*
@@ -603,7 +604,7 @@
scr->vaddr = (char*)scr->vaddr+x;
scr->paddr = paddr;
- scr->apsize = nsize;
+ scr->apsize = (int)nsize;
mtrr(npaddr, nsize, "wc");
@@ -613,8 +614,7 @@
static char*
vgalinearpci0(VGAscr *scr)
{
- int i, size, best;
- uvlong paddr;
+ int i, best;
Pcidev *p;
p = scr->pci;
@@ -645,12 +645,9 @@
&& !(p->mem[best].bar&8)))
best = i;
}
- if(best >= 0){
- paddr = p->mem[best].bar & ~0x0F;
- size = p->mem[best].size;
- return vgalinearaddr0(scr, paddr, size);
- }
- return "no video memory found on pci card";
+ if(best < 0)
+ return "no video memory found on pci card";
+ return vgalinearaddr0(scr, p->mem[best].bar&~0xF, p->mem[best].size);
}
void
@@ -665,7 +662,7 @@
}
void
-vgalinearaddr(VGAscr *scr, uvlong paddr, int size)
+vgalinearaddr(VGAscr *scr, uvlong paddr, vlong size)
{
char *err;
--- a/sys/src/9/pc/screen.h
+++ b/sys/src/9/pc/screen.h
@@ -136,7 +136,7 @@
extern Rectangle actualscreensize(VGAscr*);
extern void setactualsize(VGAscr*, Rectangle);
extern void setscreensize(VGAscr*, int, int, int, ulong, int);
-extern void addvgaseg(char*, uvlong, ulong);
+extern void addvgaseg(char*, uvlong, vlong);
extern Memdata* attachscreen(Rectangle*, ulong*, int*, int*, int*);
extern void flushmemscreen(Rectangle);
extern void cursoron(void);
@@ -159,7 +159,7 @@
extern void vgascreenwin(VGAscr*);
extern void vgaimageinit(ulong);
extern void vgalinearpci(VGAscr*);
-extern void vgalinearaddr(VGAscr*, uvlong, int);
+extern void vgalinearaddr(VGAscr*, uvlong, vlong);
extern void vgablank(VGAscr*, int);
extern Lock vgascreenlock;
--- a/sys/src/9/pc/usbehcipc.c
+++ b/sys/src/9/pc/usbehcipc.c
@@ -184,7 +184,7 @@
if(io == 0)
continue;
- print("usbehci: %#x %#x: port %llux size %d irq %d\n",
+ print("usbehci: %#x %#x: port %llux size %lld irq %d\n",
p->vid, p->did, io, p->mem[0].size, p->intl);
ctlr = malloc(sizeof(Ctlr));
--- a/sys/src/9/pc/usbohci.c
+++ b/sys/src/9/pc/usbohci.c
@@ -2401,7 +2401,7 @@
io = p->mem[0].bar & ~0xFULL;
if(io == 0)
continue;
- print("usbohci: %#x %#x: port %llux size %#x irq %d\n",
+ print("usbohci: %#x %#x: port %llux size %lld irq %d\n",
p->vid, p->did, io, p->mem[0].size, p->intl);
ctlr = malloc(sizeof(Ctlr));
if(ctlr == nil){
--- a/sys/src/9/pc/usbuhci.c
+++ b/sys/src/9/pc/usbuhci.c
@@ -2146,7 +2146,7 @@
continue;
}
- print("uhci: %#x %#x: port %#ux size %#x irq %d\n",
+ print("uhci: %#x %#x: port %#ux size %lld irq %d\n",
p->vid, p->did, io, p->mem[4].size, p->intl);
ctlr = malloc(sizeof(Ctlr));
--- a/sys/src/9/pc/vga.c
+++ b/sys/src/9/pc/vga.c
@@ -252,11 +252,11 @@
}
void
-addvgaseg(char *name, uvlong pa, ulong size)
+addvgaseg(char *name, uvlong pa, vlong size)
{
Physseg seg;
- if((uintptr)pa != pa || size == 0 || -(uintptr)pa < size){
+ if((uintptr)pa != pa || size <= 0 || -(uintptr)pa < size){
print("addvgaseg %s: bad address %llux-%llux pc %#p\n",
name, pa, pa+size, getcallerpc(&name));
return;
--- a/sys/src/9/pc/vganeomagic.c
+++ b/sys/src/9/pc/vganeomagic.c
@@ -29,7 +29,7 @@
Pcidev *p;
int bar, curoff, vmsize;
uvlong ioaddr;
- ulong iosize;
+ vlong iosize;
/*
* scr->mmio holds the virtual address of the cursor registers
@@ -78,7 +78,7 @@
default:
return;
}
- if(p->mem[bar].bar & 1)
+ if(p->mem[bar].bar & 1 || p->mem[bar].size == 0)
return;
ioaddr = p->mem[bar].bar & ~0x0F;
iosize = p->mem[bar].size;
--- a/sys/src/9/pc64/fns.h
+++ b/sys/src/9/pc64/fns.h
@@ -162,14 +162,14 @@
uvlong tscticks(uvlong*);
ulong umballoc(ulong, ulong, ulong);
void umbfree(ulong, ulong);
-uvlong upaalloc(uvlong, ulong, ulong);
-uvlong upaallocwin(uvlong, ulong, ulong, ulong);
-void upafree(uvlong, ulong);
+uvlong upaalloc(uvlong, uvlong, uvlong);
+uvlong upaallocwin(uvlong, uvlong, uvlong, uvlong);
+void upafree(uvlong, uvlong);
void vectortable(void);
void vmxprocrestore(Proc *);
void vmxshutdown(void);
-void* vmap(uvlong, int);
-void vunmap(void*, int);
+void* vmap(uvlong, vlong);
+void vunmap(void*, vlong);
void wbinvd(void);
void writeconf(void);
int wrmsr(int, vlong);
--- a/sys/src/9/pc64/mem.h
+++ b/sys/src/9/pc64/mem.h
@@ -53,10 +53,10 @@
#define KZERO (0xffffffff80000000ull)
#define KTZERO (KZERO+1*MiB+64*KiB)
-#define VMAP (0xffffff0000000000ull)
-#define VMAPSIZE (512ull*GiB)
+#define VMAP (0xfffffe8000000000ull)
+#define VMAPSIZE (1024ull*GiB)
-#define KMAP (0xfffffe8000000000ull)
+#define KMAP (0xfffffe0000000000ull)
#define KMAPSIZE (2*MiB)
/*
--- a/sys/src/9/pc64/mmu.c
+++ b/sys/src/9/pc64/mmu.c
@@ -584,13 +584,13 @@
* synchronization is being done.
*/
void*
-vmap(uvlong pa, int size)
+vmap(uvlong pa, vlong size)
{
uintptr va;
int o;
if(pa < BY2PG || size <= 0 || -pa < size || pa+size > VMAPSIZE){
- print("vmap pa=%llux size=%d pc=%#p\n", pa, size, getcallerpc(&pa));
+ print("vmap pa=%llux size=%lld pc=%#p\n", pa, size, getcallerpc(&pa));
return nil;
}
va = pa+VMAP;
@@ -607,7 +607,7 @@
}
void
-vunmap(void *v, int)
+vunmap(void *v, vlong)
{
paddr(v); /* will panic on error */
}
--- a/sys/src/9/pc64/squidboy.c
+++ b/sys/src/9/pc64/squidboy.c
@@ -32,7 +32,7 @@
void
mpstartap(Apic* apic)
{
- uintptr *apbootp, *pml4, *pdp0;
+ uintptr *apbootp, *pml4, *pdp0, v;
Segdesc *gdt;
Mach *mach;
uchar *p;
@@ -65,8 +65,11 @@
* map KZERO (note that we share the KZERO (and VMAP)
* PDP between processors.
*/
- pml4[PTLX(KZERO, 3)] = MACHP(0)->pml4[PTLX(KZERO, 3)];
- pml4[PTLX(VMAP, 3)] = MACHP(0)->pml4[PTLX(VMAP, 3)];
+ *mmuwalk(pml4, KZERO, 3, 0) = *mmuwalk(m->pml4, KZERO, 3, 0);
+ for(v = VMAP; v < VMAP+VMAPSIZE; v += PGLSZ(3)){
+ mmuwalk(m->pml4, v, 2, 1); /* force create */
+ *mmuwalk(pml4, v, 3, 0) = *mmuwalk(m->pml4, v, 3, 0);
+ }
/* double map */
pml4[0] = PADDR(pdp0) | PTEWRITE|PTEVALID;
--- a/sys/src/9/port/devpnp.c
+++ b/sys/src/9/port/devpnp.c
@@ -545,7 +545,8 @@
for(i=0; i<nelem(p->mem); i++){
if(p->mem[i].size == 0)
continue;
- w = seprint(w, ebuf, " %d:%.8llux %d", i, (uvlong)p->mem[i].bar, p->mem[i].size);
+ w = seprint(w, ebuf, " %d:%.8llux %lld", i,
+ p->mem[i].bar, p->mem[i].size);
}
*w++ = '\n';
*w = '\0';
--- a/sys/src/9/port/pci.c
+++ b/sys/src/9/port/pci.c
@@ -10,7 +10,7 @@
struct Pcisiz
{
Pcidev* dev;
- int siz;
+ vlong siz;
int bar;
int typ;
};
@@ -162,25 +162,41 @@
iunlock(&pcicfglock);
}
-int
+vlong
pcibarsize(Pcidev *p, int rno)
{
- int v, size;
+ vlong size;
+ int v;
ilock(&pcicfglock);
+
v = pcicfgrw32(p->tbdf, rno, 0, 1);
pcicfgrw32(p->tbdf, rno, -1, 0);
- size = pcicfgrw32(p->tbdf, rno, 0, 1);
+ size = (int)pcicfgrw32(p->tbdf, rno, 0, 1);
pcicfgrw32(p->tbdf, rno, v, 0);
+
+ if(rno == PciEBAR0 || rno == PciEBAR1)
+ size &= ~0x7FFLL;
+ else if(v & 1)
+ size = (short)size & ~0x3LL;
+ else {
+ size &= ~0xFLL;
+
+ if(size >= 0 && (v&7)==4 && rno < PciBAR0+4*(nelem(p->mem)-1)){
+ rno += 4;
+ v = pcicfgrw32(p->tbdf, rno, 0, 1);
+ pcicfgrw32(p->tbdf, rno, -1, 0);
+ size |= (vlong)pcicfgrw32(p->tbdf, rno, 0, 1)<<32;
+ pcicfgrw32(p->tbdf, rno, v, 0);
+ }
+ }
+
iunlock(&pcicfglock);
- if(rno == PciEBAR0 || rno == PciEBAR1){
- size &= ~0x7FF;
- } else if(v & 1){
- size = (short)size;
- size &= ~3;
- } else {
- size &= ~0xF;
+ if(size > 0){
+ print("pcibarsize: %T invalid bar rno %x mask %llux\n",
+ p->tbdf, rno, (uvlong)size);
+ return 0;
}
return -size;
@@ -216,30 +232,31 @@
static int
pcisizcmp(void *a, void *b)
{
- Pcisiz *aa, *bb;
+ Pcisiz *aa = a, *bb = b;
- aa = a;
- bb = b;
- return aa->siz - bb->siz;
+ if(aa->siz > bb->siz)
+ return 1;
+ if(aa->siz < bb->siz)
+ return -1;
+ return 0;
}
-static ulong
-pcimask(ulong v)
+static vlong
+pcimask(vlong v)
{
- ulong m;
+ uvlong m;
- m = BI2BY*sizeof(v);
- for(m = 1<<(m-1); m != 0; m >>= 1) {
+ for(m = 1ULL<<63; m != 0; m >>= 1) {
if(m & v)
break;
}
m--;
- if((v & m) == 0)
- return v;
-
- v |= m;
- return v+1;
+ if(v & m){
+ v |= m;
+ v++;
+ }
+ return v;
}
void
@@ -246,9 +263,10 @@
pcibusmap(Pcidev *root, uvlong *pmema, ulong *pioa, int wrreg)
{
Pcidev *p;
- int ntb, i, size, rno, hole;
+ int ntb, i, rno;
uvlong mema, smema;
ulong ioa, sioa, v;
+ vlong hole, size;
Pcisiz *table, *tptr, *mtb, *itb;
ioa = *pioa;
@@ -348,7 +366,7 @@
mtb->bar = i;
mtb->siz = size;
mtb->typ = v & 7;
- if(mtb->typ & 4)
+ if(mtb->typ == 4)
i++;
mtb++;
}
@@ -478,7 +496,7 @@
}
static int
-pcivalidbar(Pcidev *p, uvlong bar, int size)
+pcivalidbar(Pcidev *p, uvlong bar, vlong size)
{
if(bar & 1){
bar &= ~3;
@@ -572,7 +590,8 @@
p->mem[i].size = pcibarsize(p, rno);
if((p->mem[i].bar & 7) == 4 && i < nelem(p->mem)-1){
rno += 4;
- p->mem[i++].bar |= (uvlong)pcicfgr32(p, rno) << 32;
+ p->mem[i].bar |= (uvlong)pcicfgr32(p, rno) << 32;
+ i++;
p->mem[i].bar = 0;
p->mem[i].size = 0;
}
@@ -827,16 +846,16 @@
for(i = 0; i < nelem(p->mem); i++) {
if(t->mem[i].size == 0)
continue;
- print("%d:%.8llux %d ", i, t->mem[i].bar, t->mem[i].size);
+ print("%d:%.8llux %lld ", i, t->mem[i].bar, t->mem[i].size);
}
if(t->rom.bar || t->rom.size)
- print("rom:%.8llux %d ", t->rom.bar, t->rom.size);
+ print("rom:%.8llux %lld ", t->rom.bar, t->rom.size);
if(t->ioa.bar || t->ioa.size)
- print("ioa:%.8llux-%.8llux %d ", t->ioa.bar, t->ioa.bar+t->ioa.size, t->ioa.size);
+ print("ioa:%.8llux-%.8llux %lld ", t->ioa.bar, t->ioa.bar+t->ioa.size, t->ioa.size);
if(t->mema.bar || t->mema.size)
- print("mema:%.8llux-%.8llux %d ", t->mema.bar, t->mema.bar+t->mema.size, t->mema.size);
+ print("mema:%.8llux-%.8llux %lld ", t->mema.bar, t->mema.bar+t->mema.size, t->mema.size);
if(t->prefa.bar || t->prefa.size)
- print("prefa:%.8llux-%.8llux %llud ", t->prefa.bar, t->prefa.bar+t->prefa.size, t->prefa.size);
+ print("prefa:%.8llux-%.8llux %lld ", t->prefa.bar, t->prefa.bar+t->prefa.size, t->prefa.size);
if(t->bridge)
print("->%d", BUSBNO(t->bridge->tbdf));
print("\n");
--- a/sys/src/9/port/pci.h
+++ b/sys/src/9/port/pci.h
@@ -177,22 +177,22 @@
struct {
uvlong bar; /* base address */
- int size;
+ vlong size;
} mem[6];
struct { /* expansion rom bar */
uvlong bar;
- int size;
+ vlong size;
} rom;
struct { /* 32-bit io and memory windows */
uvlong bar;
- int size;
+ vlong size;
} ioa, mema;
struct { /* 64-bit prefechable memory window */
uvlong bar;
- uvlong size;
+ vlong size;
} prefa;
Pcidev* list;
@@ -240,7 +240,7 @@
extern Pcidev* pcimatch(Pcidev* prev, int vid, int did);
extern Pcidev* pcimatchtbdf(int tbdf);
-extern int pcibarsize(Pcidev *, int rno);
+extern vlong pcibarsize(Pcidev *, int rno);
extern void pcisetbar(Pcidev *, int, uvlong);
extern uchar pciipin(Pcidev *pci, uchar pin);
--- a/sys/src/9/port/usbxhci.c
+++ b/sys/src/9/port/usbxhci.c
@@ -1814,7 +1814,7 @@
io = p->mem[0].bar & ~0x0f;
if(io == 0)
continue;
- print("usbxhci: %#x %#x: port %llux size %d irq %d\n",
+ print("usbxhci: %#x %#x: port %llux size %lld irq %d\n",
p->vid, p->did, io, p->mem[0].size, p->intl);
mmio = vmap(io, p->mem[0].size);
if(mmio == nil){