diff --git a/sys/man/1/git b/sys/man/1/git index 5f1e7cef6..d4681e273 100644 --- a/sys/man/1/git +++ b/sys/man/1/git @@ -96,6 +96,10 @@ git/pull, git/rm, git/serve .I expr ] [ +.B -n +.I count +] +[ .B -s ] [ @@ -384,6 +388,11 @@ The .I -s option shows a summary of the commit, instead of the full message. The +.I -n count +option stops printing messages after +.I count +messages. +The .I -e expr option shows commits matching the query expression provided. The expression is in the syntax of diff --git a/sys/src/9/imx8/ccm.c b/sys/src/9/imx8/ccm.c index ffec22d52..21a0321aa 100644 --- a/sys/src/9/imx8/ccm.c +++ b/sys/src/9/imx8/ccm.c @@ -1075,6 +1075,90 @@ enablepll(int input) } } +enum { + CCM_ANALOG_PLLOUT_MONITOR_CFG = 0x74/4, + PLLOUT_MONITOR_CLK_CKE = 1<<4, + CCM_ANALOG_FRAC_PLLOUT_DIV_CFG = 0x78/4, + CCM_ANALOG_SCCG_PLLOUT_DIV_CFG = 0x7C/4, +}; + +static struct { + uchar input; + uchar reg; /* divider register */ + uchar shift; /* divider shift */ +} anapllout_input[16] = { +[0] OSC_25M_REF_CLK, +[1] OSC_27M_REF_CLK, +/* [2] HDMI_PHY_27M_CLK */ +/* [3] CLK1_P_N */ +[4] OSC_32K_REF_CLK, +[5] AUDIO_PLL1_CLK, CCM_ANALOG_FRAC_PLLOUT_DIV_CFG, 0, +[6] AUDIO_PLL2_CLK, CCM_ANALOG_FRAC_PLLOUT_DIV_CFG, 4, +[7] GPU_PLL_CLK, CCM_ANALOG_FRAC_PLLOUT_DIV_CFG, 12, +[8] VPU_PLL_CLK, CCM_ANALOG_FRAC_PLLOUT_DIV_CFG, 16, +[9] VIDEO_PLL1_CLK, CCM_ANALOG_FRAC_PLLOUT_DIV_CFG, 8, +[10] ARM_PLL_CLK, CCM_ANALOG_FRAC_PLLOUT_DIV_CFG, 20, +[11] SYSTEM_PLL1_CLK, CCM_ANALOG_SCCG_PLLOUT_DIV_CFG, 0, +[12] SYSTEM_PLL2_CLK, CCM_ANALOG_SCCG_PLLOUT_DIV_CFG, 4, +[13] SYSTEM_PLL3_CLK, CCM_ANALOG_SCCG_PLLOUT_DIV_CFG, 8, +[14] VIDEO_PLL2_CLK, CCM_ANALOG_SCCG_PLLOUT_DIV_CFG, 16, +[15] DRAM_PLL1_CLK, CCM_ANALOG_SCCG_PLLOUT_DIV_CFG, 12, +}; + +static void +setanapllout(int input, int freq) +{ + int mux, div, reg; + + for(mux = 0; mux < nelem(anapllout_input); mux++) + if(anapllout_input[mux].input == input) + goto Muxok; + panic("setanapllout: bad input clock\n"); + return; +Muxok: + anatop[CCM_ANALOG_PLLOUT_MONITOR_CFG] = mux; + if(freq <= 0) + return; + div = input_clk_freq[input] / freq; + if(div < 1 || div > 8){ + panic("setanapllout: divider out of range\n"); + return; + } + enablepll(input); + reg = anapllout_input[mux].reg; + if(reg){ + int shift = anapllout_input[mux].shift; + anatop[reg] = (anatop[reg] & ~(7<> shift) & 7)+1; + } else { + div = 1; + } + return freq / div; +} + static u32int clkgate(Clock *gate, u32int val) { @@ -1330,6 +1414,11 @@ setclkrate(char *name, char *source, int freq) { int root, input; + if(cistrcmp(name, "ccm_analog_pllout") == 0){ + setanapllout(lookinputclk(source), freq); + return; + } + if((root = lookrootclk(name)) < 0) panic("setclkrate: clock %s not defined", name); if(source == nil) @@ -1346,6 +1435,9 @@ getclkrate(char *name) { int root, input; + if(cistrcmp(name, "ccm_analog_pllout") == 0) + return getanapllout(); + if((root = lookrootclk(name)) >= 0) return rootclkgetcfg(root, &input); diff --git a/sys/src/9/imx8/fns.h b/sys/src/9/imx8/fns.h index 735225372..9958da735 100644 --- a/sys/src/9/imx8/fns.h +++ b/sys/src/9/imx8/fns.h @@ -159,3 +159,10 @@ extern uint iomuxgpr(int gpr, uint set, uint mask); #define GPIO_PIN(n, m) ((n)<<5 | (m)) extern void gpioout(uint pin, int set); extern int gpioin(uint pin); + +/* pciimx */ +extern int pcicfgrw8(int tbdf, int rno, int data, int read); +extern int pcicfgrw16(int tbdf, int rno, int data, int read); +extern int pcicfgrw32(int tbdf, int rno, int data, int read); +extern void pciintrenable(int tbdf, void (*f)(Ureg*, void*), void *a); +extern void pciintrdisable(int tbdf, void (*f)(Ureg*, void*), void *a); diff --git a/sys/src/9/imx8/gic.c b/sys/src/9/imx8/gic.c index bfff2eada..6c3052e1d 100644 --- a/sys/src/9/imx8/gic.c +++ b/sys/src/9/imx8/gic.c @@ -254,6 +254,11 @@ intrenable(int irq, void (*f)(Ureg*, void*), void *a, int tbdf, char *) u32int intid; int cpu, prio; + if(BUSTYPE(tbdf) == BusPCI){ + pciintrenable(tbdf, f, a); + return; + } + if(tbdf != BUSUNKNOWN) return; @@ -306,6 +311,10 @@ intrenable(int irq, void (*f)(Ureg*, void*), void *a, int tbdf, char *) } void -intrdisable(int, void (*)(Ureg*, void*), void *, int, char*) +intrdisable(int tbdf, void (*f)(Ureg*, void*), void *a, int, char*) { + if(BUSTYPE(tbdf) == BusPCI){ + pciintrdisable(tbdf, f, a); + return; + } } diff --git a/sys/src/9/imx8/io.h b/sys/src/9/imx8/io.h index 38a1ce0f3..c98fd3bdf 100644 --- a/sys/src/9/imx8/io.h +++ b/sys/src/9/imx8/io.h @@ -28,7 +28,12 @@ enum { IRQsctr0 = SPI+47, IRQsctr1 = SPI+48, + IRQpci2 = SPI+74, + IRQenet1 = SPI+118, + + IRQpci1 = SPI+122, }; #define BUSUNKNOWN (-1) +#define PCIWADDR(x) PADDR(x) diff --git a/sys/src/9/imx8/pciimx.c b/sys/src/9/imx8/pciimx.c new file mode 100644 index 000000000..fbfca1546 --- /dev/null +++ b/sys/src/9/imx8/pciimx.c @@ -0,0 +1,497 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "../port/pci.h" + +typedef struct Intvec Intvec; +struct Intvec +{ + Pcidev *p; + void (*f)(Ureg*, void*); + void *a; +}; + +typedef struct Ctlr Ctlr; +struct Ctlr +{ + uvlong mem_base; + uvlong mem_size; + uvlong cfg_base; + uvlong cfg_size; + uvlong io_base; + uvlong io_size; + + int bno, ubn; + int irq; + + u32int *dbi; + u32int *cfg; + Pcidev *bridge; + + Lock; + Intvec vec[32]; +}; + +static Ctlr ctlrs[2] = { + { + 0x18000000, 0x7f00000, + 0x1ff00000, 0x80000, + 0x1ff80000, 0x10000, + 0, 127, IRQpci1, + (u32int*)(VIRTIO + 0x3800000), + }, + { + 0x20000000, 0x7f00000, + 0x27f00000, 0x80000, + 0x27f80000, 0x10000, + 128, 255, IRQpci2, + (u32int*)(VIRTIO + 0x3c00000), + }, +}; + +enum { + IATU_MAX = 8, + IATU_INBOUND = 1<<0, + IATU_INDEX_SHIFT = 1, + + IATU_OFFSET = 0x300000/4, + IATU_STRIDE = 0x100/4, + + IATU_REGION_CTRL_1 = 0x00/4, + CTRL_1_FUNC_NUM_SHIFT = 20, + CTRL_1_FUNC_NUM_MASK = 7<dbi[IATU_OFFSET + IATU_STRIDE*index]; + reg[IATU_REGION_CTRL_2] &= ~CTRL_2_REGION_EN; + } +} + +static void +iatucfg(Ctlr *ctlr, int index, u32int type, uvlong target, uvlong base, uvlong size) +{ + uvlong limit = base + size - 1; + u32int *reg; + + assert(size > 0); + assert(index < IATU_MAX); + assert((index & IATU_INBOUND) == 0); + + reg = &ctlr->dbi[IATU_OFFSET + IATU_STRIDE*index]; + reg[IATU_REGION_CTRL_2] &= ~CTRL_2_REGION_EN; + + reg[IATU_LWR_BSAE_ADDR] = base; + reg[IATU_UPPER_BASE_ADDR] = base >> 32; + reg[IATU_LWR_LIMIT_ADDR] = limit; + reg[IATU_UPPER_LIMIT_ADDR] = limit >> 32; + reg[IATU_LWR_TARGET_ADDR] = target; + reg[IATU_UPPER_TARGET_ADDR] = target >> 32; + + type &= CTRL_1_TYPE_MASK; + if(((size-1)>>32) != 0) + type |= CTRL_1_INCREASE_REGION_SIZ; + + reg[IATU_REGION_CTRL_1] = type; + reg[IATU_REGION_CTRL_2] = CTRL_2_REGION_EN; + + while((reg[IATU_REGION_CTRL_2] & CTRL_2_REGION_EN) == 0) + microdelay(10); +} + +static Ctlr* +bus2ctlr(int bno) +{ + Ctlr *ctlr; + + for(ctlr = ctlrs; ctlr < &ctlrs[nelem(ctlrs)]; ctlr++) + if(bno >= ctlr->bno && bno <= ctlr->ubn) + return ctlr; + return nil; +} + +static void* +cfgaddr(int tbdf, int rno) +{ + Ctlr *ctlr; + + ctlr = bus2ctlr(BUSBNO(tbdf)); + if(ctlr == nil) + return nil; + + if(pciparentdev == nil){ + if(BUSDNO(tbdf) != 0 || BUSFNO(tbdf) != 0) + return nil; + return (uchar*)ctlr->dbi + rno; + } + + iatucfg(ctlr, 0<parent==nil? CTRL_1_TYPE_CFG0: CTRL_1_TYPE_CFG1, + BUSBNO(tbdf)<<24 | BUSDNO(tbdf)<<19 | BUSFNO(tbdf)<<16, + ctlr->cfg_base, ctlr->cfg_size); + + return (uchar*)ctlr->cfg + rno; +} + +int +pcicfgrw32(int tbdf, int rno, int data, int read) +{ + u32int *p; + + if((p = cfgaddr(tbdf, rno & ~3)) != nil){ + if(read) + data = *p; + else + *p = data; + } else { + data = -1; + } + return data; +} + +int +pcicfgrw16(int tbdf, int rno, int data, int read) +{ + u16int *p; + + if((p = cfgaddr(tbdf, rno & ~1)) != nil){ + if(read) + data = *p; + else + *p = data; + } else { + data = -1; + } + return data; +} + +int +pcicfgrw8(int tbdf, int rno, int data, int read) +{ + u8int *p; + + if((p = cfgaddr(tbdf, rno)) != nil){ + if(read) + data = *p; + else + *p = data; + } else { + data = -1; + } + return data; +} + +static u16int msimsg; +#define MSI_TARGET_ADDR PADDR(&msimsg) + +enum { + MSI_CAP_ID = 0x50/4, + PCI_MSI_ENABLE = 1<<16, + + MSI_CTRL_ADDR = 0x820/4, + MSI_CTRL_UPPER_ADDR = 0x824/4, + MSI_CTRL_INT_0_EN = 0x828/4, + MSI_CTRL_INT_0_MASK = 0x82C/4, + MSI_CTRL_INT_0_STATUS = 0x830/4, + + MISC_CONTROL_1 = 0x8BC/4, + DBI_RO_WR_EN = 1<<0, +}; + +static void +pciinterrupt(Ureg *ureg, void *arg) +{ + Ctlr *ctlr = arg; + Intvec *vec; + u32int status; + + status = ctlr->dbi[MSI_CTRL_INT_0_STATUS]; + if(status == 0) + return; + ctlr->dbi[MSI_CTRL_INT_0_STATUS] = status; + + ilock(ctlr); + for(vec = ctlr->vec; status != 0 && vec < &ctlr->vec[nelem(ctlr->vec)]; vec++, status >>= 1){ + if((status & 1) != 0 && vec->f != nil) + (*vec->f)(ureg, vec->a); + } + iunlock(ctlr); +} + +static void +pciintrinit(Ctlr *ctlr) +{ + ctlr->dbi[MSI_CTRL_INT_0_EN] = 0; + ctlr->dbi[MSI_CTRL_INT_0_MASK] = 0; + ctlr->dbi[MSI_CTRL_INT_0_STATUS] = -1; + ctlr->dbi[MSI_CTRL_ADDR] = MSI_TARGET_ADDR; + ctlr->dbi[MSI_CTRL_UPPER_ADDR] = MSI_TARGET_ADDR >> 32; + + intrenable(ctlr->irq+0, pciinterrupt, ctlr, BUSUNKNOWN, "pci"); + intrenable(ctlr->irq+1, pciinterrupt, ctlr, BUSUNKNOWN, "pci"); + intrenable(ctlr->irq+2, pciinterrupt, ctlr, BUSUNKNOWN, "pci"); + intrenable(ctlr->irq+3, pciinterrupt, ctlr, BUSUNKNOWN, "pci"); + + ctlr->dbi[MSI_CAP_ID] |= PCI_MSI_ENABLE; +} + +void +pciintrenable(int tbdf, void (*f)(Ureg*, void*), void *a) +{ + Ctlr *ctlr; + Intvec *vec; + Pcidev *p; + + ctlr = bus2ctlr(BUSBNO(tbdf)); + if(ctlr == nil){ + print("pciintrenable: %T: unknown controller\n", tbdf); + return; + } + + if((p = pcimatchtbdf(tbdf)) == nil){ + print("pciintrenable: %T: unknown device\n", tbdf); + return; + } + if(pcimsidisable(p) < 0){ + print("pciintrenable: %T: device doesnt support vec\n", tbdf); + return; + } + + ilock(ctlr); + for(vec = ctlr->vec; vec < &ctlr->vec[nelem(ctlr->vec)]; vec++){ + if(vec->p == p){ + ctlr->dbi[MSI_CTRL_INT_0_EN] &= ~(1 << (vec - ctlr->vec)); + vec->p = nil; + break; + } + } + for(vec = ctlr->vec; vec < &ctlr->vec[nelem(ctlr->vec)]; vec++){ + if(vec->p == nil){ + vec->p = p; + vec->a = a; + vec->f = f; + break; + } + } + iunlock(ctlr); + + if(vec >= &ctlr->vec[nelem(ctlr->vec)]){ + print("pciintrenable: %T: out of isr slots\n", tbdf); + return; + } + ctlr->dbi[MSI_CTRL_INT_0_EN] |= (1 << (vec - ctlr->vec)); + pcimsienable(p, MSI_TARGET_ADDR, vec - ctlr->vec); +} + +void +pciintrdisable(int tbdf, void (*f)(Ureg*, void*), void *a) +{ + Ctlr *ctlr; + Intvec *vec; + + ctlr = bus2ctlr(BUSBNO(tbdf)); + if(ctlr == nil){ + print("pciintrenable: %T: unknown controller\n", tbdf); + return; + } + + ilock(ctlr); + for(vec = ctlr->vec; vec < &ctlr->vec[nelem(ctlr->vec)]; vec++){ + if(vec->p == nil) + continue; + if(vec->p->tbdf == tbdf && vec->f == f && vec->a == a){ + ctlr->dbi[MSI_CTRL_INT_0_EN] &= ~(1 << (vec - ctlr->vec)); + vec->f = nil; + vec->a = nil; + vec->p = nil; + break; + } + } + iunlock(ctlr); +} + +static void +rootinit(Ctlr *ctlr) +{ + uvlong base; + ulong ioa; + + iatuinit(ctlr); + + ctlr->cfg = vmap(ctlr->cfg_base, ctlr->cfg_size); + if(ctlr->cfg == nil) + return; + + ctlr->dbi[MISC_CONTROL_1] |= DBI_RO_WR_EN; + + /* bus number */ + ctlr->dbi[PciPBN/4] &= ~0xFFFFFF; + ctlr->dbi[PciPBN/4] |= ctlr->bno | (ctlr->bno+1)<<8 | ctlr->ubn<<16; + + /* command */ + ctlr->dbi[PciPCR/4] &= ~0xFFFF; + ctlr->dbi[PciPCR/4] |= IOen | MEMen | MASen | SErrEn; + + /* device class/subclass */ + ctlr->dbi[PciRID/4] &= ~0xFFFF0000; + ctlr->dbi[PciRID/4] |= 0x06040000; + + ctlr->dbi[PciBAR0/4] = 0; + ctlr->dbi[PciBAR1/4] = 0; + + ctlr->dbi[MISC_CONTROL_1] &= ~DBI_RO_WR_EN; + + ctlr->ubn = pciscan(ctlr->bno, &ctlr->bridge, nil); + if(ctlr->bridge == nil || ctlr->bridge->bridge == nil) + return; + + pciintrinit(ctlr); + + iatucfg(ctlr, 1<io_base, ctlr->io_base, ctlr->io_size); + iatucfg(ctlr, 2<mem_base, ctlr->mem_base, ctlr->mem_size); + + ioa = ctlr->io_base; + base = ctlr->mem_base; + pcibusmap(ctlr->bridge, &base, &ioa, 1); + + pcihinv(ctlr->bridge); +} + +static void +pcicfginit(void) +{ + fmtinstall('T', tbdffmt); + rootinit(&ctlrs[0]); + rootinit(&ctlrs[1]); +} + +enum { + SRC_PCIEPHY_RCR = 0x2C/4, + SRC_PCIE2_RCR = 0x48/4, + PCIE_CTRL_APP_XFER_PENDING = 1<<16, + PCIE_CTRL_APP_UNLOCK_MSG = 1<<15, + PCIE_CTRL_SYS_INT = 1<<14, + PCIE_CTRL_CFG_L1_AUX = 1<<12, + PCIE_CTRL_APPS_TURNOFF = 1<<11, + PCIE_CTRL_APPS_PME = 1<<10, + PCIE_CTRL_APPS_EXIT = 1<<9, + PCIE_CTRL_APPS_ENTER = 1<<8, + PCIE_CTRL_APPS_READY = 1<<7, + PCIE_CTRL_APPS_EN = 1<<6, + PCIE_CTRL_APPS_RST = 1<<5, + PCIE_CTRL_APPS_CLK_REQ = 1<<4, + PCIE_PERST = 1<<3, + PCIE_BTN = 1<<2, + PCIE_G_RST = 1<<1, + PCIE_PHY_POWER_ON_RESET_N = 1<<0, +}; + +static u32int *resetc = (u32int*)(VIRTIO + 0x390000); + +void +pciimxlink(void) +{ + resetc[SRC_PCIEPHY_RCR] |= PCIE_BTN | PCIE_G_RST; + resetc[SRC_PCIE2_RCR] |= PCIE_BTN | PCIE_G_RST; + + resetc[SRC_PCIEPHY_RCR] |= PCIE_CTRL_APPS_EN; + resetc[SRC_PCIE2_RCR] |= PCIE_CTRL_APPS_EN; + + setclkgate("pcie_clk_rst.auxclk", 0); + setclkgate("pcie2_clk_rst.auxclk", 0); + + iomuxpad("pad_ecspi1_mosi", "gpio5_io07", "~LVTTL ~HYS ~PUE ~ODE FAST 45_OHM"); + iomuxpad("pad_sai5_rxd2", "gpio3_io23", "~LVTTL ~HYS ~PUE ~ODE FAST 45_OHM"); + + gpioout(GPIO_PIN(5, 7), 0); + gpioout(GPIO_PIN(3, 23), 0); + + powerup("pcie"); + powerup("pcie2"); + + /* configure monitor CLK2 output internal reference clock for PCIE1 */ + setclkrate("ccm_analog_pllout", "system_pll1_clk", 100*Mhz); + delay(10); + + /* PCIE1_REF_USE_PAD=0 */ + iomuxgpr(14, 0<<9, 1<<9); + + /* PCIE2_REF_USE_PAD=1 */ + iomuxgpr(16, 1<<9, 1<<9); + + /* PCIE1_CTRL_DEVICE_TYPE=ROOT, PCIE2_CTRL_DEVICE_TYPE=ROOT */ + iomuxgpr(12, 4<<12 | 4<<8, 0xF<<12 | 0xF<<8); + + setclkrate("ccm_pcie1_ctrl_clk_root", "system_pll2_div4", 250*Mhz); + setclkrate("ccm_pcie2_ctrl_clk_root", "system_pll2_div4", 250*Mhz); + + setclkrate("pcie_clk_rst.auxclk", "system_pll2_div10", 100*Mhz); + setclkrate("pcie2_clk_rst.auxclk", "system_pll2_div10", 100*Mhz); + + setclkrate("pcie_phy.ref_alt_clk_p", "system_pll2_div10", 100*Mhz); + setclkrate("pcie2_phy.ref_alt_clk_p", "system_pll2_div10", 100*Mhz); + + setclkgate("pcie_clk_rst.auxclk", 1); + setclkgate("pcie2_clk_rst.auxclk", 1); + + /* PCIE1_CLKREQ_B_OVERRIDE=0 PCIE1_CLKREQ_B_OVERRIDE_EN=1 */ + iomuxgpr(14, 1<<10, 3<<10); + + /* PCIE2_CLKREQ_B_OVERRIDE=0 PCIE2_CLKREQ_B_OVERRIDE_EN=1 */ + iomuxgpr(16, 1<<10, 3<<10); + + delay(100); + gpioout(GPIO_PIN(5, 7), 1); + gpioout(GPIO_PIN(3, 23), 1); + delay(1); + + resetc[SRC_PCIEPHY_RCR] &= ~(PCIE_BTN | PCIE_G_RST); + resetc[SRC_PCIE2_RCR] &= ~(PCIE_BTN | PCIE_G_RST); + + pcicfginit(); +} diff --git a/sys/src/9/imx8/reform b/sys/src/9/imx8/reform index 747451665..0fba5fc20 100644 --- a/sys/src/9/imx8/reform +++ b/sys/src/9/imx8/reform @@ -27,6 +27,7 @@ link ethermedium loopbackmedium i2cimx devi2c + pciimx pci ip tcp udp @@ -44,6 +45,7 @@ misc uartimx iomux sdmmc usdhc + sdnvme pci port int cpuserver = 0; bootdir diff --git a/sys/src/9/port/pci.c b/sys/src/9/port/pci.c index 5ca42d5ac..da1541bce 100644 --- a/sys/src/9/port/pci.c +++ b/sys/src/9/port/pci.c @@ -16,6 +16,7 @@ struct Pcisiz }; int pcimaxdno; +Pcidev *pciparentdev; static Lock pcicfglock; static Pcidev *pcilist, **pcitail; @@ -113,6 +114,8 @@ pcicfgr8(Pcidev* p, int rno) int data; ilock(&pcicfglock); + pciparentdev = p->parent; + data = pcicfgrw8(p->tbdf, rno, 0, 1); iunlock(&pcicfglock); @@ -122,6 +125,8 @@ void pcicfgw8(Pcidev* p, int rno, int data) { ilock(&pcicfglock); + pciparentdev = p->parent; + pcicfgrw8(p->tbdf, rno, data, 0); iunlock(&pcicfglock); } @@ -131,6 +136,8 @@ pcicfgr16(Pcidev* p, int rno) int data; ilock(&pcicfglock); + pciparentdev = p->parent; + data = pcicfgrw16(p->tbdf, rno, 0, 1); iunlock(&pcicfglock); @@ -140,6 +147,8 @@ void pcicfgw16(Pcidev* p, int rno, int data) { ilock(&pcicfglock); + pciparentdev = p->parent; + pcicfgrw16(p->tbdf, rno, data, 0); iunlock(&pcicfglock); } @@ -149,6 +158,8 @@ pcicfgr32(Pcidev* p, int rno) int data; ilock(&pcicfglock); + pciparentdev = p->parent; + data = pcicfgrw32(p->tbdf, rno, 0, 1); iunlock(&pcicfglock); @@ -158,6 +169,8 @@ void pcicfgw32(Pcidev* p, int rno, int data) { ilock(&pcicfglock); + pciparentdev = p->parent; + pcicfgrw32(p->tbdf, rno, data, 0); iunlock(&pcicfglock); } @@ -169,6 +182,7 @@ pcibarsize(Pcidev *p, int rno) int v; ilock(&pcicfglock); + pciparentdev = p->parent; v = pcicfgrw32(p->tbdf, rno, 0, 1); pcicfgrw32(p->tbdf, rno, -1, 0); @@ -206,6 +220,8 @@ void pcisetbar(Pcidev *p, int rno, uvlong bar) { ilock(&pcicfglock); + pciparentdev = p->parent; + pcicfgrw32(p->tbdf, rno, bar, 0); if((bar&7) == 4 && rno >= PciBAR0 && rno < PciBAR0+4*(nelem(p->mem)-1)) pcicfgrw32(p->tbdf, rno+4, bar>>32, 0); @@ -216,6 +232,8 @@ void pcisetwin(Pcidev *p, uvlong base, uvlong limit) { ilock(&pcicfglock); + pciparentdev = p->parent; + if(base & 1){ pcicfgrw16(p->tbdf, PciIBR, (limit & 0xF000)|((base & 0xF000)>>8), 0); pcicfgrw32(p->tbdf, PciIUBR, (limit & 0xFFFF0000)|(base>>16), 0); @@ -534,12 +552,15 @@ pciscan(int bno, Pcidev** list, Pcidev *parent) tbdf = MKBUS(BusPCI, bno, dno, fno); lock(&pcicfglock); + pciparentdev = parent; + l = pcicfgrw32(tbdf, PciVID, 0, 1); unlock(&pcicfglock); if(l == 0xFFFFFFFF || l == 0) continue; p = pcidevalloc(); + p->parent = parent; p->tbdf = tbdf; p->vid = l; p->did = l>>16; @@ -622,7 +643,6 @@ pciscan(int bno, Pcidev** list, Pcidev *parent) break; } - p->parent = parent; if(head != nil) *tail = p; else diff --git a/sys/src/9/port/pci.h b/sys/src/9/port/pci.h index 6119966b5..204f53c9a 100644 --- a/sys/src/9/port/pci.h +++ b/sys/src/9/port/pci.h @@ -223,6 +223,7 @@ enum }; extern int pcimaxdno; +extern Pcidev *pciparentdev; extern void pcidevfree(Pcidev* pcidev); diff --git a/sys/src/9/pc/sdnvme.c b/sys/src/9/port/sdnvme.c similarity index 95% rename from sys/src/9/pc/sdnvme.c rename to sys/src/9/port/sdnvme.c index aa985d932..1708e6ac4 100644 --- a/sys/src/9/pc/sdnvme.c +++ b/sys/src/9/port/sdnvme.c @@ -135,6 +135,7 @@ qcmd(WS *ws, Ctlr *ctlr, int adm, u32int opc, u32int nsid, void *mptr, void *dat e[5] = 0; } if(len > 0){ + dmaflush(1, data, len); pa = PCIWADDR(data); e[6] = pa; e[7] = pa>>32; @@ -173,6 +174,7 @@ nvmeintr(Ureg *, void *arg) phaseshift = 16 - cq->shift; for(;;){ e = &cq->base[(cq->head & cq->mask)<<2]; + dmaflush(0, e, 32); if(((e[3] ^ (cq->head << phaseshift)) & 0x10000) == 0) break; @@ -204,11 +206,12 @@ wdone(void *arg) } static u32int -wcmd(WS *ws) +wcmd(WS *ws, u32int *e) { SQ *sq = ws->queue; Ctlr *ctlr = sq->ctlr; + if(e != nil) dmaflush(1, e, 64); coherence(); ctlr->reg[DBell + ((sq-ctlr->sq)*2+0 << ctlr->dstrd)] = sq->tail & sq->mask; if(sq > ctlr->sq) { @@ -263,11 +266,12 @@ nvmebio(SDunit *u, int lun, int write, void *a, long count, uvlong lba) e[13] = (count>n)<<6; /* sequential request */ e[14] = 0; e[15] = 0; - checkstatus(wcmd(&ws), write ? "write" : "read"); + checkstatus(wcmd(&ws, e), write ? "write" : "read"); p += n*s; count -= n; lba += n; } + if(!write) dmaflush(0, a, p - (uchar*)a); return p - (uchar*)a; } @@ -313,10 +317,11 @@ nvmeonline(SDunit *u) e = qcmd(&ws, ctlr, 1, 0x06, ctlr->nsid[u->subno], nil, info, 0x1000); e[10] = 0; // identify namespace - if(wcmd(&ws) != 0){ + if(wcmd(&ws, e) != 0){ free(info); return 0; } + dmaflush(0, info, 0x1000); p = info; u->sectors = p[0] | p[1]<<8 | p[2]<<16 | p[3]<<24 | (u64int)p[4]<<32 @@ -405,7 +410,7 @@ setupqueues(Ctlr *ctlr) e = qcmd(&ws, ctlr, 1, 0x05, 0, nil, cq->base, 1<cq) | cq->mask<<16; e[11] = 3; /* IEN | PC */ - checkstatus(wcmd(&ws), "create completion queue"); + checkstatus(wcmd(&ws, e), "create completion queue"); st = 0; @@ -416,8 +421,7 @@ setupqueues(Ctlr *ctlr) e = qcmd(&ws, ctlr, 1, 0x01, 0, nil, sq->base, 0x1000); e[10] = i | sq->mask<<16; e[11] = (cq - ctlr->cq)<<16 | 1; /* CQID<<16 | PC */ - - st = wcmd(&ws); + st = wcmd(&ws, e); if(st != 0){ free(sq->base); free(sq->wait); @@ -451,11 +455,14 @@ identify(Ctlr *ctlr) e = qcmd(&ws, ctlr, 1, 0x06, 0, nil, ctlr->ident, 0x1000); e[10] = 1; // identify controller - checkstatus(wcmd(&ws), "identify controller"); + checkstatus(wcmd(&ws, e), "identify controller"); + dmaflush(0, ctlr->ident, 0x1000); e = qcmd(&ws, ctlr, 1, 0x06, 0, nil, ctlr->nsid, 0x1000); e[10] = 2; // namespace list - if(wcmd(&ws) != 0) + if(wcmd(&ws, e) == 0) + dmaflush(0, ctlr->nsid, 0x1000); + else ctlr->nsid[0] = 1; /* assume namespace #1 */ ctlr->nnsid = 0; @@ -532,10 +539,12 @@ nvmeenable(SDev *sd) } pa = PCIWADDR(cqalloc(ctlr, &ctlr->cq[0], ctlr->mpsshift)); + dmaflush(1, ctlr->cq[0].base, 1<mpsshift); ctlr->reg[ACQBase0] = pa; ctlr->reg[ACQBase1] = pa>>32; pa = PCIWADDR(sqalloc(ctlr, &ctlr->sq[0], ctlr->mpsshift)); + dmaflush(1, ctlr->sq[0].base, 1<mpsshift); ctlr->reg[ASQBase0] = pa; ctlr->reg[ASQBase1] = pa>>32; diff --git a/sys/src/cmd/git/compat b/sys/src/cmd/git/compat old mode 100755 new mode 100644 index 25d14308f..f61ff71e9 --- a/sys/src/cmd/git/compat +++ b/sys/src/cmd/git/compat @@ -94,7 +94,7 @@ fn cmd_rev-parse{ echo `{dcmd git9/branch | sed s@^heads/@@g} shift case * - dprint option $opt + die unknown option $opt } shift } @@ -112,6 +112,15 @@ fn cmd_show-ref{ echo `{cat $gitroot/.git/refs/$b} refs/$b } +fn cmd_rev-parse{ + switch($1){ + case --git-dir + echo `{git/conf -r}^/.git + case * + die 'unknown rev-parse '$* + } +} + fn cmd_remote{ if({! ~ $#* 3 && ! ~ $#* 4} || ! ~ $1 add) die unimplemented remote cmd $* @@ -125,6 +134,44 @@ fn cmd_remote{ } } +fn cmd_log{ + count=() + format='' + while(~ $1 -*){ + switch($1){ + case --format + format=$2 + shift + case '--format='* + format=`{echo $1 | sed 's/--format=//g'} + case -n + count=-n$2 + shift + case -n* + count=$1 + case * + dprint option $opt + } + shift + } + @{cd $gitroot && git/fs} + switch($format){ + case '' + git/log $count + case '%H:%ct' + for(c in `{git/log -s $count| awk '{print $1}'}) + echo $c:`{mtime $gitroot/.git/fs/object/$c/msg} + case '%h %cd' + for(c in `{git/log -s $count| awk '{print $1}'}) + echo $c `{date `{mtime $gitroot/.git/fs/object/$c/msg}} + } + +} + +fn cmd_show{ + cmd_log -n1 $* +} + fn cmd_ls-remote{ if(~ $1 -q) shift @@ -138,6 +185,9 @@ fn cmd_version{ echo git version 2.2.0 } +fn cmd_status{ + echo +} fn usage{ echo 'git ' >[1=2] @@ -158,11 +208,20 @@ if(~ $0 *compat){ exec rc } +if(~ $#gitcompatdebug 1) + echo running $* >>/tmp/gitlog + +if(~ $1 -c) + shift 2 +if(~ $1 -c*) + shift 1 if(! test -f '/env/fn#cmd_'$1) die git $1: commmand not implemented if(! ~ $1 init && ! ~ $1 clone) gitroot=`{git/conf -r} || die repo -echo $* >/tmp/gitlog -cmd_$1 $*(2-) +if(~ $#gitcompatdebug 1) + cmd_$1 $*(2-) | tee >>/tmp/gitlog +if not + cmd_$1 $*(2-) exit '' diff --git a/sys/src/cmd/git/log.c b/sys/src/cmd/git/log.c index a06c427d0..2a8f63084 100644 --- a/sys/src/cmd/git/log.c +++ b/sys/src/cmd/git/log.c @@ -14,6 +14,7 @@ Biobuf *out; char *queryexpr; char *commitid; int shortlog; +int msgcount = -1; Objset done; Objq objq; @@ -180,7 +181,7 @@ showquery(char *q) if((n = resolverefs(&h, q)) == -1) sysfatal("resolve: %r"); - for(i = 0; i < n; i++){ + for(i = 0; i < n && (msgcount == -1 || msgcount-- > 0); i++){ if((o = readobject(h[i])) == nil) sysfatal("read %H: %r", h[i]); show(o); @@ -206,7 +207,7 @@ showcommits(char *c) qinit(&objq); osinit(&done); qput(&objq, o, 0); - while(qpop(&objq, &e)){ + while(qpop(&objq, &e) && (msgcount == -1 || msgcount-- > 0)){ show(e.o); for(i = 0; i < e.o->commit->nparent; i++){ if(oshas(&done, e.o->commit->parent[i])) @@ -243,6 +244,9 @@ main(int argc, char **argv) case 's': shortlog++; break; + case 'n': + msgcount = atoi(EARGF(usage())); + break; default: usage(); break; diff --git a/sys/src/cmd/patch.c b/sys/src/cmd/patch.c index 3da0674ff..d1b9db5fe 100644 --- a/sys/src/cmd/patch.c +++ b/sys/src/cmd/patch.c @@ -287,13 +287,13 @@ hunk: while(1){ if((ln = readline(f, &lnum)) == nil){ if(oldcnt != h.oldcnt || newcnt != h.newcnt) - sysfatal("%s:%d: malformed hunk", name, lnum); + sysfatal("%s:%d: malformed hunk: mismatched counts", name, lnum); addhunk(p, &h); break; } switch(ln[0]){ default: - sysfatal("%s:%d: malformed hunk2", name, lnum); + sysfatal("%s:%d: malformed hunk: leading junk", name, lnum); goto out; case '-': addold(&h, ln); @@ -303,6 +303,12 @@ hunk: addnew(&h, ln); newcnt++; break; + case '\n': + addold(&h, " \n"); + addnew(&h, " \n"); + oldcnt++; + newcnt++; + break; case ' ': addold(&h, ln); addnew(&h, ln); @@ -312,7 +318,7 @@ hunk: } free(ln); if(oldcnt > h.oldcnt || newcnt > h.newcnt) - sysfatal("%s:%d: malformed hunk", name, lnum); + sysfatal("%s:%d: malformed hunk: oversized hunk", name, lnum); if(oldcnt < h.oldcnt || newcnt < h.newcnt) continue;