Re: ignore memory past 512GB

2018-04-19 Thread Mark Kettenis
> Date: Fri, 20 Apr 2018 14:54:29 +1000
> From: Jonathan Matthew 
> 
> On Fri, Apr 20, 2018 at 04:59:27AM +0200, Mark Kettenis wrote:
> > > Date: Fri, 20 Apr 2018 11:41:10 +1000
> > > From: Jonathan Matthew 
> > > 
> > > We just got some R6415s with 512GB of memory and found it's hard to boot 
> > > them
> > > because the kernel message buffer ends up past the 512GB boundary, but the
> > > direct map is "only" 512GB, so initmsgbuf() crashes.
> > > 
> > > I found 'mach mem =1G' moves the buffer below 512GB (but 'mach mem
> > > =2G' doesn't!), which let me write the diff below that clips memory
> > > clusters at 512GB.  This means uvm doesn't know about any memory
> > > past 512GB and the code in init_x86_64() that steals memory for
> > > buffers doesn't use it either.
> > > 
> > > With this the machine boots and I still have almost all of the memory:
> > > 
> > > OpenBSD 6.3-current (GENERIC.MP) #3: Fri Apr 20 07:51:06 AEST 2018
> > > 
> > > jonat...@r6415.embarrassm.net:/home/jonathan/src/sys/arch/amd64/compile/GENERIC.MP
> > > real mem = 547253186560 (521901MB)
> > > avail mem = 530660573184 (506077MB)
> > > 
> > > The memory layout looks like this:
> > > 
> > > boot> mach mem
> > > Region 0: type 1 at 0x0 for 572KB
> > > Region 1: type 4 at 0x8f000 for 4KB
> > > Region 2: type 1 at 0x9 for 64KB
> > > Region 3: type 1 at 0x10 for 1722364KB
> > > Region 4: type 2 at 0x692ff000 for 37888KB
> > > Region 5: type 4 at 0x6b7ff000 for 14528KB
> > > Region 6: type 3 at 0x6c62f000 for 2048KB
> > > Region 7: type 1 at 0x6c82f000 for 57156KB
> > > Region 8: type 1 at 0x1 for 132107776KB
> > > Region 9: type 1 at 0x208000 for 134217216KB
> > > Region 10: type 1 at 0x408000 for 134217216KB
> > > Region 11: type 1 at 0x608000 for 134217216KB
> > > Region 12: type 2 at 0x7000 for 524288KB
> > > Region 13: type 2 at 0xfec1 for 4KB
> > > Region 14: type 2 at 0xfed8 for 4KB
> > > Region 15: type 2 at 0x207f38 for 12800KB
> > > Region 16: type 2 at 0x407ff8 for 512KB
> > > Region 17: type 2 at 0x607ff8 for 512KB
> > > Region 18: type 2 at 0x807ff8 for 512KB
> > > Low ram: 640KB  High ram: 2358272KB
> > > Total free memory: 536539580KB
> > > 
> > > 
> > > ok?  or should we look at expanding the direct map instead?
> > 
> > I'd say we should do something like this regardless.  However...
> > 
> > > Index: machdep.c
> > > ===
> > > RCS file: /cvs/src/sys/arch/amd64/amd64/machdep.c,v
> > > retrieving revision 1.241
> > > diff -u -p -u -p -r1.241 machdep.c
> > > --- machdep.c 12 Apr 2018 17:13:43 -  1.241
> > > +++ machdep.c 19 Apr 2018 23:32:23 -
> > > @@ -1439,6 +1439,16 @@ init_x86_64(paddr_t first_avail)
> > >   continue;
> > >   }
> > >  
> > > + /*
> > > +  * The direct map is limited to 512GB of memory, so
> > > +  * discard anything above that.
> > > +  */
> > > + if (e1 >= (uint64_t)512*1024*1024*1024) {
> > > + e1 = ((uint64_t)512*1024*1024*1024) - PAGE_SIZE;
> > 
> > Why are you subtracting PAGE_SIZE here?
> 
> Mostly because I didn't read the code closely enough.  I thought that was
> supposed to be the address of the last valid page, but it looks like it's
> the next one.  Not subtracting PAGE_SIZE here also works.

Then I think you should it commit with that bit removed.

Cheers,

Mark

> > > + if (s1 > e1)
> > > + continue;
> > > + }
> > > +
> > >   /* Crop stuff into "640K hole" */
> > >   if (s1 < IOM_BEGIN && e1 > IOM_BEGIN)
> > >   e1 = IOM_BEGIN;
> > > 
> > > 
> 



Re: ccp(4): quick and dirty driver for amd crypto coprocessors

2018-04-22 Thread Mark Kettenis
> From: David Gwynne 
> Date: Mon, 23 Apr 2018 10:38:57 +1000
> 
> > On 21 Apr 2018, at 05:52, Christian Weisgerber  wrote:
> > 
> > On 2018-04-20, Mark Kettenis  wrote:
> > 
> >> At some point I tried playing with this on the APU, which has the v3
> >> engine I think.  Couldn't get anything to work (but I didn't try very
> >> hard).  Would be interesting to see whether this actually works on
> >> that machine.
> > 
> > It attaches.  How can I tell if it works?
> > 
> > ccp0 at pci0 dev 8 function 0 "AMD Cryptographic Co-processor v3" rev 0x00
> 
> i added printfs in the timeout, but that's pretty invasive. how do
> we tell if any rng is working?

We can't tell.  Our random code doesn't really care.  Adding data that
isn't really random to the entropy pool shouldn't make our output less
random and we don't count entropy anymore.



Re: arm64: GPIO "pin bus" drivers

2018-04-24 Thread Mark Kettenis
> Date: Tue, 24 Apr 2018 08:32:40 +0300
> From: Artturi Alm 
> 
> Hi,
> 
> pine64 still being my only arm64-sbc, i won't bother w/
> gpio* at rkgpio?
> etc., but i would like to have these enabled for arm64,
> as atleast pine64 is equipped w/plenty of headers/pins brought out, and
> gpio* at sxipio?
> is there already:)

Thanks.  The gpioiic(4) is probably not all that useful considering
that there pins for a real i2c controller available as well.

Anyway, I committed the diff.  Thanks.



Re: fill device description with product name in uvideo(4)

2018-04-24 Thread Mark Kettenis
> Date: Tue, 24 Apr 2018 16:04:34 +0100
> From: Stuart Henderson 
> 
> On 2018/04/24 16:34, Landry Breuil wrote:
> > Hi,
> > 
> > here's a diff to reuse usbd_devinfo_vp() (exposed in usbdivar.h) in
> > VIDIOC_QUERYCAP ioctl callback, this way we can fill v4l2_capability
> > card struct member with the actual usb product name instead of a dummy
> > "Generic USB video class device".
> 
> Generally I think this is a good idea, but some devices have crap in
> v/p, is that likely to cause any problems?

Spaces are trimmed, but the strings are not otherwise sanitized.  The
mozilla code seems to interpret the string as UTF8 which opens up
additional ways to misinterpret the string.  Maybe some further
sanitization similar to what we do for scsi devices (scsi_strvis()) is
desirable.

An alternative would be to pass 0 instead of 1 for the last argument,
but then the string doesn't necessarily match what's printed in dmesg.

> > Firefox uses that ioctl to get the user-facing device name in
> > https://dxr.mozilla.org/mozilla-central/source/media/webrtc/trunk/webrtc/modules/video_capture/linux/device_info_linux.cc#313
> > so that's helpful when you have several devices
> > and the webrtc doorhanger asks you which camera you want to
> > share.. cf http://i.imgur.com/uLnWw6u.png
> > 
> > USB_MAX_STRING_LEN is 127 and card is 32 in v4l2_capability, so strlcpy
> > should take care of null-terminating/truncating.

I'm almost tempted to suggest putting the device name (uvideo0,
uvideo1, etc.) there to have something that is consistent.
> 
> > Index: usb_subr.c
> > ===
> > RCS file: /cvs/src/sys/dev/usb/usb_subr.c,v
> > retrieving revision 1.134
> > diff -u -r1.134 usb_subr.c
> > --- usb_subr.c  8 Apr 2017 02:57:25 -   1.134
> > +++ usb_subr.c  24 Apr 2018 14:20:00 -
> > @@ -61,8 +61,6 @@
> >  
> >  usbd_statususbd_set_config(struct usbd_device *, int);
> >  void   usbd_devinfo(struct usbd_device *, int, char *, size_t);
> > -void   usbd_devinfo_vp(struct usbd_device *, char *, size_t,
> > -   char *, size_t, int);
> >  char   *usbd_get_device_string(struct usbd_device *, uByte);
> >  char   *usbd_get_string(struct usbd_device *, int, char *, 
> > size_t);
> >  intusbd_getnewaddr(struct usbd_bus *);
> > Index: usbdivar.h
> > ===
> > RCS file: /cvs/src/sys/dev/usb/usbdivar.h,v
> > retrieving revision 1.73
> > diff -u -r1.73 usbdivar.h
> > --- usbdivar.h  3 Feb 2018 13:37:37 -   1.73
> > +++ usbdivar.h  24 Apr 2018 14:20:00 -
> > @@ -257,6 +257,8 @@
> >  usbd_statususb_insert_transfer(struct usbd_xfer *);
> >  void   usb_transfer_complete(struct usbd_xfer *);
> >  intusbd_detach(struct usbd_device *, struct device *);
> > +void   usbd_devinfo_vp(struct usbd_device *, char *, size_t,
> > +   char *, size_t, int);
> >  
> >  /* Routines from usb.c */
> >  void   usb_needs_explore(struct usbd_device *, int);
> > Index: uvideo.c
> > ===
> > RCS file: /cvs/src/sys/dev/usb/uvideo.c,v
> > retrieving revision 1.196
> > diff -u -r1.196 uvideo.c
> > --- uvideo.c30 Dec 2017 23:08:29 -  1.196
> > +++ uvideo.c24 Apr 2018 14:20:00 -
> > @@ -2781,11 +2781,14 @@
> >  uvideo_querycap(void *v, struct v4l2_capability *caps)
> >  {
> > struct uvideo_softc *sc = v;
> > +   char vendor[USB_MAX_STRING_LEN];
> > +   char product[USB_MAX_STRING_LEN];
> >  
> > bzero(caps, sizeof(*caps));
> > strlcpy(caps->driver, DEVNAME(sc), sizeof(caps->driver));
> > -   strlcpy(caps->card, "Generic USB video class device",
> > -   sizeof(caps->card));
> > +   usbd_devinfo_vp(sc->sc_udev, vendor, sizeof (vendor), product,
> > +   sizeof (product), 1);
> > +   strlcpy(caps->card, product, sizeof(caps->card));
> > strlcpy(caps->bus_info, "usb", sizeof(caps->bus_info));
> >  
> > caps->version = 1;
> 
> 



Make binutils not barf on binaries linked with lld

2018-04-24 Thread Mark Kettenis
So lld generates .gnu.hash sections that our ancient binutils doesn't
grok.  With the diff below (taken from FreeBSD's binutils, so GPLv2)
fixes this.

ok?


Index: gnu/usr.bin/binutils-2.17/bfd/elf.c
===
RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/bfd/elf.c,v
retrieving revision 1.12
diff -u -p -r1.12 elf.c
--- gnu/usr.bin/binutils-2.17/bfd/elf.c 10 Aug 2016 20:46:08 -  1.12
+++ gnu/usr.bin/binutils-2.17/bfd/elf.c 24 Apr 2018 18:41:12 -
@@ -1825,6 +1825,7 @@ bfd_section_from_shdr (bfd *abfd, unsign
 case SHT_FINI_ARRAY:   /* .fini_array section.  */
 case SHT_PREINIT_ARRAY:/* .preinit_array section.  */
 case SHT_GNU_LIBLIST:  /* .gnu.liblist section.  */
+case SHT_GNU_HASH: /* .gnu.hash section.  */
   return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
 
 case SHT_DYNAMIC:  /* Dynamic linking information.  */
@@ -2264,6 +2265,7 @@ static const struct bfd_elf_special_sect
   { ".gnu.version_r", 14,  0, SHT_GNU_verneed, 0 },
   { ".gnu.liblist",   12,  0, SHT_GNU_LIBLIST, SHF_ALLOC },
   { ".gnu.conflict",  13,  0, SHT_RELA, SHF_ALLOC },
+  { ".gnu.hash",   9,  0, SHT_GNU_HASH, SHF_ALLOC },
   { NULL,  0,  0, 0,0 }
 };
 
@@ -2785,6 +2787,10 @@ elf_fake_sections (bfd *abfd, asection *
 case SHT_GROUP:
   this_hdr->sh_entsize = 4;
   break;
+
+case SHT_GNU_HASH:
+  this_hdr->sh_entsize = bed->s->arch_size == 64 ? 0 : 4;
+  break;
 }
 
   if ((asect->flags & SEC_ALLOC) != 0)
@@ -3230,6 +3236,7 @@ assign_section_numbers (bfd *abfd, struc
  break;
 
case SHT_HASH:
+   case SHT_GNU_HASH:
case SHT_GNU_versym:
  /* sh_link is the section header index of the symbol table
 this hash table or version table is for.  */
Index: gnu/usr.bin/binutils-2.17/include/elf/common.h
===
RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/include/elf/common.h,v
retrieving revision 1.7
diff -u -p -r1.7 common.h
--- gnu/usr.bin/binutils-2.17/include/elf/common.h  25 Jan 2017 08:56:08 
-  1.7
+++ gnu/usr.bin/binutils-2.17/include/elf/common.h  24 Apr 2018 18:41:12 
-
@@ -343,6 +343,7 @@
 #define SHT_LOOS   0x6000  /* First of OS specific semantics */
 #define SHT_HIOS   0x6fff  /* Last of OS specific semantics */
 
+#define SHT_GNU_HASH   0x6ff6  /* GNU style symbol hash table */
 #define SHT_GNU_LIBLIST0x6ff7  /* List of prelink dependencies 
*/
 
 /* The next three section types are defined by Solaris, and are named



Re: Make binutils not barf on binaries linked with lld

2018-04-24 Thread Mark Kettenis
> From: Philip Guenther 
> Date: Tue, 24 Apr 2018 21:09:32 +0200
> 
> On Tue, Apr 24, 2018 at 8:43 PM, Mark Kettenis 
> wrote:
> 
> > So lld generates .gnu.hash sections that our ancient binutils doesn't
> > grok.  With the diff below (taken from FreeBSD's binutils, so GPLv2)
> > fixes this.
> >
> > ok?
> >
> > --- gnu/usr.bin/binutils-2.17/bfd/elf.c 10 Aug 2016 20:46:08 -
> > 1.12
> > +++ gnu/usr.bin/binutils-2.17/bfd/elf.c 24 Apr 2018 18:41:12 -
> >
> ...
> 
> > @@ -2785,6 +2787,10 @@ elf_fake_sections (bfd *abfd, asection *
> >  case SHT_GROUP:
> >this_hdr->sh_entsize = 4;
> >break;
> > +
> > +case SHT_GNU_HASH:
> > +  this_hdr->sh_entsize = bed->s->arch_size == 64 ? 0 : 4;
> > +  break;
> >
> 
> The entity size is _zero_ for 64bit archs?  (Or does that not really matter
> because you're not trying to make it dump the actual hash table itself?)

Yes.  The binaries produced by lld have it as 0 on amd64 and 4 on
armv7, which matches the code I copied from FreeBSD.

> Other than that possibly being wrong, ok guenther

Thanks



tech@openbsd.org

2018-04-26 Thread Mark Kettenis
> Date: Thu, 26 Apr 2018 10:35:45 +0300
> From: Artturi Alm 
> 
> Hi,
> 
> wrote simple gpio indicator sensor driver, and spotted this.
> 
> decided to keep the /* XXX */ for tech@, so this should be 'safe'
> for anyone not using gpioctl(8) no matter what :)
> 
> i don't really see any risk, only w/o one might need to do this
> w/ext resistors.
> 
> comments?

Can you please actually describe what the intention of your patches is
in normal English, preferably with proper punctation and without silly
abbreviations.  One of the reason your diffs get ignored is because it
simply takes too much effort to figure out what you actually mean.

Thanks,

Mark

> diff --git sys/dev/fdt/sxipio.c sys/dev/fdt/sxipio.c
> index fe231d6bfd7..46f1212dee9 100644
> --- sys/dev/fdt/sxipio.c
> +++ sys/dev/fdt/sxipio.c
> @@ -356,6 +356,11 @@ sxipio_config_pin(void *cookie, uint32_t *cells, int 
> config)
>   mux = (config & GPIO_CONFIG_OUTPUT) ? 1 : 0;
>   off = (pin & 0x7) << 2;
>   SXICMS4(sc, SXIPIO_CFG(port, pin), 0x7 << off, mux << off);
> + if (config & GPIO_CONFIG_PULLUP)
> + SXICMS4(sc, SXIPIO_PUL(port, pin), 0x3 << off, 1 << off);
> + else if (config & GPIO_CONFIG_PULLDOWN)
> + SXICMS4(sc, SXIPIO_PUL(port, pin), 0x3 << off, 2 << off);
> + /* XXX should else _PUL 0 << off expl. here? */
>  }
>  
>  int
> @@ -446,15 +451,18 @@ sxipio_pin_ctl(void *cookie, int pin, int flags)
>  {
>   struct sxipio_gpio *gpio = cookie;
>   uint32_t cells[3];
> + int config;
>  
>   cells[0] = gpio->port;
>   cells[1] = pin;
>   cells[2] = 0;
>  
> - if (ISSET(flags, GPIO_PIN_OUTPUT))
> - sxipio_config_pin(gpio->sc, cells, GPIO_CONFIG_OUTPUT);
> - else
> - sxipio_config_pin(gpio->sc, cells, 0);
> + config = ISSET(flags, GPIO_PIN_OUTPUT) ? GPIO_CONFIG_OUTPUT : 0;
> + if (ISSET(flags, GPIO_PIN_PULLUP))
> + config |= GPIO_CONFIG_PULLDOWN;
> + else if (ISSET(flags, GPIO_PIN_PULLDOWN))
> + config |= GPIO_CONFIG_PULLDOWN;
> + sxipio_config_pin(gpio->sc, cells, config);
>  }
>  
>  void
> @@ -503,7 +511,8 @@ sxipio_attach_gpio(struct device *parent)
>   state = (reg >> pin) & 1;
>  
>   sc->sc_gpio_pins[port][pin].pin_caps =
> - GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
> + GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |
> + GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN;
>   sc->sc_gpio_pins[port][pin].pin_flags = flags;
>   sc->sc_gpio_pins[port][pin].pin_state = state;
>   sc->sc_gpio_pins[port][pin].pin_num = pin;
> diff --git sys/dev/ofw/ofw_gpio.h sys/dev/ofw/ofw_gpio.h
> index 52b2fe08453..0917ace3b67 100644
> --- sys/dev/ofw/ofw_gpio.h
> +++ sys/dev/ofw/ofw_gpio.h
> @@ -37,6 +37,8 @@ voidgpio_controller_register(struct gpio_controller 
> *);
>  
>  #define GPIO_CONFIG_INPUT0x
>  #define GPIO_CONFIG_OUTPUT   0x0001
> +#define GPIO_CONFIG_PULLUP   0x0002
> +#define GPIO_CONFIG_PULLDOWN 0x0004
>  void gpio_controller_config_pin(uint32_t *, int);
>  
>  int  gpio_controller_get_pin(uint32_t *);
> 



Re: rasops: implement scrollback for inteldrm and efifb

2018-04-27 Thread Mark Kettenis
> Date: Fri, 27 Apr 2018 09:33:31 -0500
> From: joshua stein 
> 
> On Tue, 17 Apr 2018 at 07:52:28 +0200, Mark Kettenis wrote:
> > > Date: Mon, 16 Apr 2018 10:45:52 -0500
> > > From: joshua stein 
> > 
> > Does this do the right thing for early consoles?  The initial
> > efifb_bs[] doesn't have space for the scrollback.  At the point where
> > the scrollback code gets code, we've replaced that with a malloc'ed
> > buffer?
> 
> Here is a new version that puts the scrollback count into each 
> rasops_screen in case it changes later, which allows it to cope with 
> the count being 0 if no scrollback has been allocated.
> 
> Though the scrollback callback won't be called until wsdisplay 
> formally attaches later after each rasops_screen is allocated 
> anyway.

Two small nits below.  Otherwise this looks fine, so ok kettenis@ if
you fix those.

> Index: arch/amd64/amd64/efifb.c
> ===
> RCS file: /cvs/src/sys/arch/amd64/amd64/efifb.c,v
> retrieving revision 1.15
> diff -u -p -u -p -r1.15 efifb.c
> --- arch/amd64/amd64/efifb.c  25 Apr 2018 00:46:28 -  1.15
> +++ arch/amd64/amd64/efifb.c  27 Apr 2018 14:27:22 -
> @@ -101,6 +101,7 @@ intefifb_show_screen(void *, void *, i
>   void *);
>  int   efifb_list_font(void *, struct wsdisplay_font *);
>  int   efifb_load_font(void *, void *, struct wsdisplay_font *);
> +void  efifb_scrollback(void *, void *, int lines);
>  void  efifb_efiinfo_init(struct efifb *);
>  void  efifb_cnattach_common(void);
>  
> @@ -133,7 +134,8 @@ struct wsdisplay_accessops efifb_accesso
>   .free_screen = efifb_free_screen,
>   .show_screen = efifb_show_screen,
>   .load_font = efifb_load_font,
> - .list_font = efifb_list_font
> + .list_font = efifb_list_font,
> + .scrollback = efifb_scrollback,
>  };
>  
>  struct cfdriver efifb_cd = {
> @@ -397,6 +399,15 @@ efifb_list_font(void *v, struct wsdispla
>   struct rasops_info  *ri = &sc->sc_fb->rinfo;
>  
>   return (rasops_list_font(ri, font));
> +}
> +
> +void
> +efifb_scrollback(void *v, void *cookie, int lines)
> +{
> + struct efifb_softc  *sc = v;
> + struct rasops_info  *ri = &sc->sc_fb->rinfo;
> +
> + rasops_scrollback(ri, cookie, lines);
>  }
>  
>  int
> Index: dev/rasops/rasops.c
> ===
> RCS file: /cvs/src/sys/dev/rasops/rasops.c,v
> retrieving revision 1.52
> diff -u -p -u -p -r1.52 rasops.c
> --- dev/rasops/rasops.c   20 Apr 2018 16:09:37 -  1.52
> +++ dev/rasops/rasops.c   27 Apr 2018 14:27:23 -
> @@ -1373,6 +1373,11 @@ struct rasops_screen {
>   int rs_visible;
>   int rs_crow;
>   int rs_ccol;
> +
> + int rs_sbscreens;
> +#define RS_SCROLLBACK_SCREENS 5
> + int rs_dispoffset;  /* rs_bs index, start of our actual screen */
> + int rs_visibleoffset;   /* rs_bs index, current scrollback screen */
>  };
>  
>  int
> @@ -1387,13 +1392,16 @@ rasops_alloc_screen(void *v, void **cook
>   if (scr == NULL)
>   return (ENOMEM);
>  
> - scr->rs_bs = mallocarray(ri->ri_rows,
> + scr->rs_sbscreens = RS_SCROLLBACK_SCREENS;
> + scr->rs_bs = mallocarray(ri->ri_rows * (scr->rs_sbscreens + 1),
>   ri->ri_cols * sizeof(struct wsdisplay_charcell), M_DEVBUF,
>   M_NOWAIT);
>   if (scr->rs_bs == NULL) {
>   free(scr, M_DEVBUF, sizeof(*scr));
>   return (ENOMEM);
>   }
> + scr->rs_visibleoffset = scr->rs_dispoffset = ri->ri_rows *
> + scr->rs_sbscreens * ri->ri_cols;
>  
>   *cookiep = scr;
>   *curxp = 0;
> @@ -1405,13 +1413,19 @@ rasops_alloc_screen(void *v, void **cook
>   scr->rs_crow = -1;
>   scr->rs_ccol = -1;
>  
> + for (i = 0; i < scr->rs_dispoffset; i++) {
> + scr->rs_bs[i].uc = ' ';
> + scr->rs_bs[i].attr = *attrp;
> + }
> +
>   if (ri->ri_bs && scr->rs_visible) {
> - memcpy(scr->rs_bs, ri->ri_bs, ri->ri_rows * ri->ri_cols *
> + memcpy(scr->rs_bs + scr->rs_dispoffset, ri->ri_bs,
> + ri->ri_rows * ri->ri_cols *
>   sizeof(struct wsdisplay_charcell));
>   } else {
>   for (i = 0; i < ri->ri_rows * ri->ri_cols; i++) {
> - scr->rs_bs[i].uc = ' ';
> - scr->rs_bs[i].attr = *attrp;
> +  

Re: avoid uninitialised attr in rasops_scrollback()

2018-04-29 Thread Mark Kettenis
> Date: Sun, 29 Apr 2018 16:46:30 +1000
> From: Jonathan Gray 
> 
> Don't use attr uninitialised.  Avoids glitches seen when using
> scrollback with radeondrm.

ok kettenis@

> Index: rasops.c
> ===
> RCS file: /cvs/src/sys/dev/rasops/rasops.c,v
> retrieving revision 1.53
> diff -u -p -r1.53 rasops.c
> --- rasops.c  27 Apr 2018 21:36:12 -  1.53
> +++ rasops.c  29 Apr 2018 06:34:19 -
> @@ -1927,6 +1927,7 @@ rasops_scrollback(void *v, void *cookie,
>   return;
>  
>   rasops_cursor(ri, 0, 0, 0);
> + ri->ri_alloc_attr(ri, 0, 0, 0, &attr);
>   ri->ri_eraserows(ri, 0, ri->ri_rows, attr);
>   for (row = 0; row < ri->ri_rows; row++) {
>   for (col = 0; col < ri->ri_cols; col++) {
> 
> 



bytgpio(4) cleanup

2018-04-30 Thread Mark Kettenis
Found this diff on one of my machines.  Not sure why I didn't commit
it yet.  The purpose of acpi_register_gpio() was to avoid duplicating
the code.

ok?


Index: dev/acpi/bytgpio.c
===
RCS file: /cvs/src/sys/dev/acpi/bytgpio.c,v
retrieving revision 1.12
diff -u -p -r1.12 bytgpio.c
--- dev/acpi/bytgpio.c  25 Oct 2016 06:48:58 -  1.12
+++ dev/acpi/bytgpio.c  30 Apr 2018 07:13:48 -
@@ -125,8 +125,6 @@ bytgpio_attach(struct device *parent, st
struct acpi_attach_args *aaa = aux;
struct bytgpio_softc *sc = (struct bytgpio_softc *)self;
struct aml_value res;
-   struct aml_value arg[2];
-   struct aml_node *node;
int64_t uid;
uint32_t reg;
int i;
@@ -219,16 +217,7 @@ bytgpio_attach(struct device *parent, st
 
printf(", %d pins\n", sc->sc_npins);
 
-   /* Register address space. */
-   memset(&arg, 0, sizeof(arg));
-   arg[0].type = AML_OBJTYPE_INTEGER;
-   arg[0].v_integer = ACPI_OPREG_GPIO;
-   arg[1].type = AML_OBJTYPE_INTEGER;
-   arg[1].v_integer = 1;
-   node = aml_searchname(sc->sc_node, "_REG");
-   if (node && aml_evalnode(sc->sc_acpi, node, 2, arg, NULL))
-   printf("%s: _REG failed\n", sc->sc_dev.dv_xname);
-   
+   acpi_register_gpio(sc->sc_acpi, sc->sc_node);
return;
 
 unmap:



SMCCC 1.1 support for psci(4)

2018-05-01 Thread Mark Kettenis
So after adding a quick hack to mitigate Spectre variant 2 to ARM
Trusted Firmware (ATF), ARM actually designed a proper solution that
minimizes the performance loss and makes the presence of the
workaround detectable.  This is all documented in an update of the SMC
Calling Convention (SMCCC) standard.

The diff below implements support for this solution while keeping
support for the hack.  While ARM strongly suggests vendors to update
to a version of ATF that implements SMCCC 1.1 the current ATF for the
Marvell ARMADA 8040 hasn't been updated yet (but does include the
initial hack).

Unfortunately the SMCCC 1.1 implementation in ATF doesn't quite
implement the spec.  As a result we have to check whether the
workaround is implemented by issuing the relevant calls on each of the
CPUs that might be affected.  This is important for big.LITTLE designs
such as the RK3399 that include both Cortex-A53 cores that aren't
vulnerable and Cortex-A72 cores that are.

ok?


Index: dev/fdt/psci.c
===
RCS file: /cvs/src/sys/dev/fdt/psci.c,v
retrieving revision 1.6
diff -u -p -r1.6 psci.c
--- dev/fdt/psci.c  23 Feb 2018 19:08:56 -  1.6
+++ dev/fdt/psci.c  1 May 2018 09:35:14 -
@@ -31,14 +31,19 @@
 extern void (*cpuresetfn)(void);
 extern void (*powerdownfn)(void);
 
-#define PSCI_VERSION   0x8400
-#define SYSTEM_OFF 0x8408
-#define SYSTEM_RESET   0x8409
+#define SMCCC_VERSION  0x8000
+#define SMCCC_ARCH_FEATURES0x8001
+#define SMCCC_ARCH_WORKAROUND_10x80008000
+
+#define PSCI_VERSION   0x8400
 #ifdef __LP64__
-#define CPU_ON 0xc403
+#define CPU_ON 0xc403
 #else
-#define CPU_ON 0x8403
+#define CPU_ON 0x8403
 #endif
+#define SYSTEM_OFF 0x8408
+#define SYSTEM_RESET   0x8409
+#define PSCI_FEATURES  0x840a
 
 struct psci_softc {
struct devicesc_dev;
@@ -48,6 +53,9 @@ struct psci_softc {
uint32_t sc_system_off;
uint32_t sc_system_reset;
uint32_t sc_cpu_on;
+
+   uint32_t sc_version;
+   uint32_t sc_smccc_version;
 };
 
 struct psci_softc *psci_sc;
@@ -60,6 +68,12 @@ void psci_powerdown(void);
 extern register_t hvc_call(register_t, register_t, register_t, register_t);
 extern register_t smc_call(register_t, register_t, register_t, register_t);
 
+int32_t smccc_version(void);
+int32_t smccc_arch_features(uint32_t);
+
+uint32_t psci_version(void);
+int32_t psci_features(uint32_t);
+
 struct cfattach psci_ca = {
sizeof(struct psci_softc), psci_match, psci_attach
 };
@@ -84,7 +98,6 @@ psci_attach(struct device *parent, struc
struct psci_softc *sc = (struct psci_softc *)self;
struct fdt_attach_args *faa = aux;
char method[128];
-   uint32_t version;
 
if (OF_getprop(faa->fa_node, "method", method, sizeof(method))) {
if (strcmp(method, "hvc") == 0)
@@ -114,8 +127,18 @@ psci_attach(struct device *parent, struc
 
psci_sc = sc;
 
-   version = psci_version();
-   printf(": PSCI %d.%d\n", version >> 16, version & 0x);
+   sc->sc_version = psci_version();
+   printf(": PSCI %d.%d", sc->sc_version >> 16, sc->sc_version & 0x);
+
+   if (sc->sc_version >= 0x1) {
+   if (psci_features(SMCCC_VERSION) == PSCI_SUCCESS) {
+   sc->sc_smccc_version = smccc_version();
+   printf(", SMCCC %d.%d", sc->sc_smccc_version >> 16,
+   sc->sc_smccc_version & 0x);
+   }
+   }
+
+   printf("\n");
 
if (sc->sc_system_off != 0)
powerdownfn = psci_powerdown;
@@ -123,22 +146,11 @@ psci_attach(struct device *parent, struc
cpuresetfn = psci_reset;
 }
 
-uint32_t
-psci_version(void)
-{
-   struct psci_softc *sc = psci_sc;
-
-   if (sc && sc->sc_callfn && sc->sc_psci_version != 0)
-   return (*sc->sc_callfn)(sc->sc_psci_version, 0, 0, 0);
-
-   /* No version support; return 0.0. */
-   return 0;
-}
-
 void
 psci_reset(void)
 {
struct psci_softc *sc = psci_sc;
+
if (sc->sc_callfn)
(*sc->sc_callfn)(sc->sc_system_reset, 0, 0, 0);
 }
@@ -147,10 +159,111 @@ void
 psci_powerdown(void)
 {
struct psci_softc *sc = psci_sc;
+
if (sc->sc_callfn)
(*sc->sc_callfn)(sc->sc_system_off, 0, 0, 0);
 }
 
+/*
+ * Firmware-based workaround for CVE-2017-5715.  We pick the
+ * appropriate mechanism based on the PSCI and SMCCC versions.  Note
+ * that ARM Trusted Firmware violates the SMCCC 1.1 specification and
+ * only reports the presence of the appropriate workaround on CPUs
+ * that are actually vulnerable.  That's why we determine the
+ * appropriate workaround the first time around.
+ */
+
+void
+psci_flush_bp_none(void)
+{
+}
+
+void
+psc

Add 1500000 baud entry to gettytab(5)

2018-05-01 Thread Mark Kettenis
The various Rockchip SoCs seem to favour 150 for the serial
console speed.  And since for some of those we still have to rely on
closed source firmware components, I think I'll have to bite the
bullit and properly support this.  Here is a first diff that adds an
appropriate entry to gettytab(5).  Not entirely sure whether the
150-baud alias is necessary.  But I don't think it'll hurt us.

ok?


Index: etc/gettytab
===
RCS file: /cvs/src/etc/gettytab,v
retrieving revision 1.5
diff -u -p -r1.5 gettytab
--- etc/gettytab10 Dec 2013 20:56:59 -  1.5
+++ etc/gettytab1 May 2018 18:51:45 -
@@ -47,6 +47,8 @@ std.57600|57600-baud:\
:sp#57600:
 std.115200|115200-baud:\
:sp#115200:
+std.150|150-baud:\
+   :sp#150:
 
 #
 # Dial in rotary tables, speed selection via 'break'



Re: reduce hppa interrupt guts awfulness

2018-05-02 Thread Mark Kettenis
> Date: Tue, 1 May 2018 21:22:12 +
> From: Miod Vallat 
> 
> B2000 and C3650 test have been done with sys/dev/ic/com.c downgraded to
> 1.166 in order to avoid freezes (bug resolution ongoing and not related
> to this diff).

So that's why my C3000 didn't come back after a reboot...

The problem is fairly obvious.  The probe for the XR17V35X that was
added in 1.167 reads from a register that is outside the standard
range of 8250 UART registers.  This obviously can't be done, so I've
reverted the com(4)-related bits of that commit.

Regarding your diff.  The approach seems reasonable to me.  The magic
number in the gscbus.c doesn't fill me with joy.

> + r[4] = cpu_gethpa(0) | (31 - irqbit);   /* iar */

I realise you're following existing practice, but maybe you could you
add a gscbus_reg struct similar to what was used in the asp/lasi/wax
code and use that?

Wither way, ok kettenis@

> $ cat levandes.vari
> Index: conf/GENERIC
> ===
> RCS file: /OpenBSD/src/sys/arch/hppa/conf/GENERIC,v
> retrieving revision 1.175
> diff -u -p -r1.175 GENERIC
> --- conf/GENERIC  14 Feb 2018 23:51:49 -  1.175
> +++ conf/GENERIC  1 May 2018 20:03:14 -
> @@ -46,21 +46,19 @@ uturn0at mainbus0 # U2/UTurn Runway IO
>  uturn1   at mainbus0
>  astro*   at mainbus0 # Astro memory & I/O controller
>  
> -lasi0at mainbus0 offset 0x10 irq 28  # LASI host adapter
> -lasi0at mainbus0 offset 0xfd0 irq 28 # LASI on C1[01]0, 
> J2[01]0
> -lasi0at phantomas0 offset 0xfd0 irq 28   # LASI on [AB]*
> -lasi0at uturn? offset 0xfd0 irq 28   # LASI on [CJ]*
> -lasi1at mainbus0 offset 0x50 irq 27  # 712 GIO card
> -asp* at mainbus0 irq 28  # this one comes w/ Viper and LEDs
> -wax* at mainbus0 irq 24  # Wax may host EISA as well
> -wax* at phantomas0 irq 24# Wax on [AB]*
> -wax* at uturn? irq 24# Wax on C*
> +lasi0at mainbus0 offset 0x10 # LASI host adapter
> +lasi0at mainbus0 offset 0xfd0# LASI on C1[01]0, 
> J2[01]0
> +lasi0at phantomas0 offset 0xfd0  # LASI on [AB]*
> +lasi0at uturn? offset 0xfd0  # LASI on [CJ]*
> +lasi1at mainbus0 offset 0x50 # 712 GIO card
> +asp* at mainbus0 # this one comes w/ Viper and LEDs
> +wax* at mainbus0 # Wax may host EISA as well
> +wax* at phantomas0   # Wax on [AB]*
> +wax* at uturn?   # Wax on C*
>  mongoose* at mainbus0 irq 17 # EISA Bus Adapter (i82350 or TI???)
>  #vmeb*   at mainbus0 irq ?   # VME bus adapter
> -dino0at phantomas? irq 26# PCI bus bridge on [AB]*
> -dino1at phantomas? irq 25
> -dino0at uturn0 irq 26# PCI bus bridge on [CJ]*
> -dino1at uturn1 irq 25
> +dino*at phantomas?   # PCI bus bridge on [AB]*
> +dino*at uturn?   # PCI bus bridge on [CJ]*
>  pci* at dino?
>  option   PCIVERBOSE
>  #pckbc0  at dino? irq 9
> @@ -176,12 +174,9 @@ onewire* at uow?
>  udl* at uhub?# DisplayLink USB displays
>  wsdisplay* at udl?
>  
> -sti0 at mainbus0 irq 11  # [H]CRX-{8,24,48}[Z] graphics
> -sti0 at phantomas0 irq 11# builtin graphics on BC*
> -sti0 at uturn? irq 11
> -sti1 at mainbus0 irq 12
> -sti1 at phantomas0 irq 12
> -sti1 at uturn? irq 12
> +sti* at mainbus0 # [H]CRX-{8,24,48}[Z] graphics
> +sti* at phantomas0   # builtin graphics on BC*
> +sti* at uturn?
>  sti* at pci? # EG-PCI, FX*
>  
>  # internal i/o space
> Index: conf/RAMDISK
> ===
> RCS file: /OpenBSD/src/sys/arch/hppa/conf/RAMDISK,v
> retrieving revision 1.109
> diff -u -p -r1.109 RAMDISK
> --- conf/RAMDISK  30 Dec 2016 22:36:07 -  1.109
> +++ conf/RAMDISK  1 May 2018 20:03:14 -
> @@ -48,20 +48,18 @@ uturn0at mainbus0 # U2/UTurn 
> Runway I
>  uturn1   at mainbus0
>  astro*   at mainbus0 # Astro memory & I/O controller
>  
> -lasi0at mainbus0 offset 0x10 irq 28  # LASI host 
> adapter
> -lasi0at mainbus0 offset 0xfd0 irq 28 # LASI on 
> C1[01]0, J2[01]0
> -lasi0at phantomas0 offset 0xfd0 irq 28   # LASI on [AB]*
> -lasi0at uturn? offset 0xfd0 irq 28   # LASI on [CJ]*
> -lasi1at mainbus0 offset 0x50 irq 27  # 712 GIO card
> -asp* at mainbus0 irq 28  # this one comes w/ Viper and LEDs
> -wax* at mainbus0 irq 24  # Wax may host EISA as well
> -wax* at phantomas0 irq 24# Wax on [AB]*
> -wax* at uturn? irq 24# Wax on C*
> +lasi0at mainbus0 offset 0x10 # LASI host adapter
> +lasi0 

Re: SMCCC 1.1 support for psci(4)

2018-05-03 Thread Mark Kettenis
> Date: Thu, 3 May 2018 08:19:01 +0100
> From: Dimitris Papastamos 

Hi Dimitris,

> On Tue, May 01, 2018 at 11:55:00AM +0200, Mark Kettenis wrote:
> > So after adding a quick hack to mitigate Spectre variant 2 to ARM
> > Trusted Firmware (ATF), ARM actually designed a proper solution that
> > minimizes the performance loss and makes the presence of the
> > workaround detectable.  This is all documented in an update of the SMC
> > Calling Convention (SMCCC) standard.
> > 
> > The diff below implements support for this solution while keeping
> > support for the hack.  While ARM strongly suggests vendors to update
> > to a version of ATF that implements SMCCC 1.1 the current ATF for the
> > Marvell ARMADA 8040 hasn't been updated yet (but does include the
> > initial hack).
> > 
> > Unfortunately the SMCCC 1.1 implementation in ATF doesn't quite
> > implement the spec.  As a result we have to check whether the
> > workaround is implemented by issuing the relevant calls on each of the
> > CPUs that might be affected.  This is important for big.LITTLE designs
> > such as the RK3399 that include both Cortex-A53 cores that aren't
> > vulnerable and Cortex-A72 cores that are.
> 
> Can you explain a bit the inconsistency between the spec and the TF
> implementation?  If there is an issue in the TF implementation I can
> fix it.
> 
> On a big.LITTLE system the expected behaviour is for
> SMCCC_ARCH_FEATURES() to return 1 for the unaffected cores
> (Cortex-A53) and 0 for the affected cores (Cortex-A72).  The call will
> only return -1 if TF is built without mitigation support for
> CVE-2017-5715.

Looks like I managed to confuse myself and drew the wrong conclusion
from the description of SMCCC_ARCH_WORKAROUND_1 in section 2.2.4.4:

  In heterogeneous systems with some PEs that require mitigation and
  others that do not, the firmware must provide a safe implementation
  of this function on all PEs.

I now notice that 2.2.4.2 explicitly spells out the results of the
SMCCC_ARCH)FEATURES call that matches the behaviour you indicate above
and doesn't actually contradict what's written in 2.2.4.4.  I'll
adjust the comments in the OpenBSD code.  Thanks for enlightening me!

> You might also want this patch:
> 
> https://github.com/ARM-software/arm-trusted-firmware/commit/59dc4ef48757e4de2dc2de13d13e43acd5d91aa0#diff-3de7e205aa9233a71ea7940aae6579fe
> 

That certainly makes the code easier to understand.  I'll see if I can
trick the Marvell folks into backporting that to their TF fork.

Thanks,

Mark

P.S. I'm still thinking about "leveraging" trusted firmware to improve
 the security of OpenBSD.  I have some ideas, but no concrete
 plans yet to implement anything.



Re: reduce hppa interrupt guts awfulness

2018-05-03 Thread Mark Kettenis
> Date: Thu, 3 May 2018 17:18:56 +
> From: Miod Vallat 
> 
> > Regarding your diff.  The approach seems reasonable to me.  The magic
> > number in the gscbus.c doesn't fill me with joy.
> > 
> > > + r[4] = cpu_gethpa(0) | (31 - irqbit);   /* iar */
> > 
> > I realise you're following existing practice, but maybe you could you
> > add a gscbus_reg struct similar to what was used in the asp/lasi/wax
> > code and use that?
> 
> I agree this wouldn't hurt, but then, locore uses hardcoded numbers
> because these offsets don't end up in genassym.cf.
> 
> Oh well, some partial cleanup can't hurt.
> 
> New diff - also, because the interrupt assignments at gsc are actually
> local to gsc interrupt controllers, there is no need to reverse the
> order of cpu_intr_findirq(). The "irq" mention in dmesg is a bit
> misleading, but fixing that would require the print function to be
> passed to pdc_scanbus() and it's a bit out of scope of these changes.

Even better.  Go for it.

> Index: conf/GENERIC
> ===
> RCS file: /OpenBSD/src/sys/arch/hppa/conf/GENERIC,v
> retrieving revision 1.175
> diff -u -p -r1.175 GENERIC
> --- conf/GENERIC  14 Feb 2018 23:51:49 -  1.175
> +++ conf/GENERIC  3 May 2018 17:08:26 -
> @@ -46,21 +46,19 @@ uturn0at mainbus0 # U2/UTurn Runway IO
>  uturn1   at mainbus0
>  astro*   at mainbus0 # Astro memory & I/O controller
>  
> -lasi0at mainbus0 offset 0x10 irq 28  # LASI host adapter
> -lasi0at mainbus0 offset 0xfd0 irq 28 # LASI on C1[01]0, 
> J2[01]0
> -lasi0at phantomas0 offset 0xfd0 irq 28   # LASI on [AB]*
> -lasi0at uturn? offset 0xfd0 irq 28   # LASI on [CJ]*
> -lasi1at mainbus0 offset 0x50 irq 27  # 712 GIO card
> -asp* at mainbus0 irq 28  # this one comes w/ Viper and LEDs
> -wax* at mainbus0 irq 24  # Wax may host EISA as well
> -wax* at phantomas0 irq 24# Wax on [AB]*
> -wax* at uturn? irq 24# Wax on C*
> +lasi0at mainbus0 offset 0x10 # LASI host adapter
> +lasi0at mainbus0 offset 0xfd0# LASI on C1[01]0, 
> J2[01]0
> +lasi0at phantomas0 offset 0xfd0  # LASI on [AB]*
> +lasi0at uturn? offset 0xfd0  # LASI on [CJ]*
> +lasi1at mainbus0 offset 0x50 # 712 GIO card
> +asp* at mainbus0 # this one comes w/ Viper and LEDs
> +wax* at mainbus0 # Wax may host EISA as well
> +wax* at phantomas0   # Wax on [AB]*
> +wax* at uturn?   # Wax on C*
>  mongoose* at mainbus0 irq 17 # EISA Bus Adapter (i82350 or TI???)
>  #vmeb*   at mainbus0 irq ?   # VME bus adapter
> -dino0at phantomas? irq 26# PCI bus bridge on [AB]*
> -dino1at phantomas? irq 25
> -dino0at uturn0 irq 26# PCI bus bridge on [CJ]*
> -dino1at uturn1 irq 25
> +dino*at phantomas?   # PCI bus bridge on [AB]*
> +dino*at uturn?   # PCI bus bridge on [CJ]*
>  pci* at dino?
>  option   PCIVERBOSE
>  #pckbc0  at dino? irq 9
> @@ -176,12 +174,9 @@ onewire* at uow?
>  udl* at uhub?# DisplayLink USB displays
>  wsdisplay* at udl?
>  
> -sti0 at mainbus0 irq 11  # [H]CRX-{8,24,48}[Z] graphics
> -sti0 at phantomas0 irq 11# builtin graphics on BC*
> -sti0 at uturn? irq 11
> -sti1 at mainbus0 irq 12
> -sti1 at phantomas0 irq 12
> -sti1 at uturn? irq 12
> +sti* at mainbus0 # [H]CRX-{8,24,48}[Z] graphics
> +sti* at phantomas0   # builtin graphics on BC*
> +sti* at uturn?
>  sti* at pci? # EG-PCI, FX*
>  
>  # internal i/o space
> Index: conf/RAMDISK
> ===
> RCS file: /OpenBSD/src/sys/arch/hppa/conf/RAMDISK,v
> retrieving revision 1.109
> diff -u -p -r1.109 RAMDISK
> --- conf/RAMDISK  30 Dec 2016 22:36:07 -  1.109
> +++ conf/RAMDISK  3 May 2018 17:08:26 -
> @@ -48,20 +48,18 @@ uturn0at mainbus0 # U2/UTurn 
> Runway I
>  uturn1   at mainbus0
>  astro*   at mainbus0 # Astro memory & I/O controller
>  
> -lasi0at mainbus0 offset 0x10 irq 28  # LASI host 
> adapter
> -lasi0at mainbus0 offset 0xfd0 irq 28 # LASI on 
> C1[01]0, J2[01]0
> -lasi0at phantomas0 offset 0xfd0 irq 28   # LASI on [AB]*
> -lasi0at uturn? offset 0xfd0 irq 28   # LASI on [CJ]*
> -lasi1at mainbus0 offset 0x50 irq 27  # 712 GIO card
> -asp* at mainbus0 irq 28  # this one comes w/ Viper and LEDs
> -wax* at mainbus0 irq 24  # Wax may host EISA as well
> -wax* at phantomas0 irq 24# Wax on [AB]*
> -wax* at uturn? irq 24# Wax on C*
> +lasi0at mai

Symlinks for shared libraries

2018-05-03 Thread Mark Kettenis
As we discussed some time ago, adding symlinks like

  libfoo.so -> libfoo.so.x.y

brings us more in line with other ELF platforms and will allow us to
drop some OpenBSD-specific code from our linkers.  It also makes it
possible for developers to easily revert a library version bump.

The symlinks will need to be added to sets of course after this goes
in.  Since the symlinks are there primarily for the sake of the
linker, it makes sense to add these symlinks to comp.tgz.

ok?


Index: share/mk/bsd.lib.mk
===
RCS file: /cvs/src/share/mk/bsd.lib.mk,v
retrieving revision 1.92
diff -u -p -r1.92 bsd.lib.mk
--- share/mk/bsd.lib.mk 14 Nov 2017 10:02:56 -  1.92
+++ share/mk/bsd.lib.mk 3 May 2018 21:02:43 -
@@ -287,6 +287,9 @@ realinstall:
 .if !defined(NOPIC) && defined(SHLIB_MAJOR) && defined(SHLIB_MINOR)
${INSTALL} ${INSTALL_COPY} -S -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
${FULLSHLIBNAME} ${DESTDIR}${LIBDIR}
+   ln -sf ${DESTDIR}${LIDIR}${FULLSHLIBNAME} \
+   ${DESTDIR}${LIBDIR}/lib${LIB}.so
+   chown -h ${LIBOWN}:${LIBGRP} ${DESTDIR}${LIBDIR}/lib${LIB}.so
 .if defined(LIBREBUILD)
${INSTALL} -d -o ${LIBOWN} -g ${LIBGRP} -m 755 \
   ${DESTDIR}/usr/share/relink/${LIBDIR}



Re: ofw/fdt: obstacle on pretty dev/fdt/X_fdt.c attachment glue for the common (ie. i2c) drivers

2018-05-04 Thread Mark Kettenis
> Date: Fri, 4 May 2018 20:56:07 +0300
> From: Artturi Alm 
> 
> Hi,
> 
> currently, I don't see how it is possible to write generic
> i2c-parent-controller-independent attachment glue in dev/fdt/,
> ie. for drivers in dev/i2c. The usual way how they are written with
> doesn't work as the devices in dev/i2c attach "at i2c" already.
> 
> visa@ just commited something in the direction i wish you would
> continue, and that would be adding "needs-flag" to
> 
> dev/ofw/files.ofw:
> 3: file   dev/ofw/fdt.c   fdt
> ->
> 3: file   dev/ofw/fdt.c   fdt needs-flag
> 
> which would allow writing cleaner glue with less pollution, imo..
> 
> I have some examples, if this isn't totally out of the question,
> of which i think most wanted might be for maxrtc(4), as many boards
> come with lacking RTC/battery and maxrtc(4) is a cheap&easy fix for it.

You completely fail to explain what the problem is.  There are several
i2c drivers for RTC chips in the tree that work on armv7 and/or arm64
and they are completely fdt-agnostic.  See for example
dev/i2c/isl1208.c.



Re: SMCCC 1.1 support for psci(4)

2018-05-04 Thread Mark Kettenis
> Date: Tue, 1 May 2018 11:55:00 +0200 (CEST)
> From: Mark Kettenis 
> 
> So after adding a quick hack to mitigate Spectre variant 2 to ARM
> Trusted Firmware (ATF), ARM actually designed a proper solution that
> minimizes the performance loss and makes the presence of the
> workaround detectable.  This is all documented in an update of the SMC
> Calling Convention (SMCCC) standard.
> 
> The diff below implements support for this solution while keeping
> support for the hack.  While ARM strongly suggests vendors to update
> to a version of ATF that implements SMCCC 1.1 the current ATF for the
> Marvell ARMADA 8040 hasn't been updated yet (but does include the
> initial hack).

So it turns out that while I wasn't paying attention, the Marvell
folks backported SMCCC 1.1 support to their ATF fork.  This means we
can drop support for the PSCI_VERSION hack without leaving
MACCHIATOBin owener out in the cold.  I think the code simplification
is worth it.  It also means we can tell whether a machine is safe or
not from a dmesg.

ok?

Index: dev/fdt/psci.c
===
RCS file: /cvs/src/sys/dev/fdt/psci.c,v
retrieving revision 1.7
diff -u -p -r1.7 psci.c
--- dev/fdt/psci.c  3 May 2018 09:45:57 -   1.7
+++ dev/fdt/psci.c  4 May 2018 18:01:04 -
@@ -54,7 +54,6 @@ struct psci_softc {
uint32_t sc_system_reset;
uint32_t sc_cpu_on;
 
-   uint32_t sc_version;
uint32_t sc_smccc_version;
 };
 
@@ -98,6 +97,7 @@ psci_attach(struct device *parent, struc
struct psci_softc *sc = (struct psci_softc *)self;
struct fdt_attach_args *faa = aux;
char method[128];
+   uint32_t version;
 
if (OF_getprop(faa->fa_node, "method", method, sizeof(method))) {
if (strcmp(method, "hvc") == 0)
@@ -127,10 +127,10 @@ psci_attach(struct device *parent, struc
 
psci_sc = sc;
 
-   sc->sc_version = psci_version();
-   printf(": PSCI %d.%d", sc->sc_version >> 16, sc->sc_version & 0x);
+   version = psci_version();
+   printf(": PSCI %d.%d", version >> 16, version & 0x);
 
-   if (sc->sc_version >= 0x1) {
+   if (version >= 0x1) {
if (psci_features(SMCCC_VERSION) == PSCI_SUCCESS) {
sc->sc_smccc_version = smccc_version();
printf(", SMCCC %d.%d", sc->sc_smccc_version >> 16,
@@ -165,11 +165,9 @@ psci_powerdown(void)
 }
 
 /*
- * Firmware-based workaround for CVE-2017-5715.  We pick the
- * appropriate mechanism based on the PSCI and SMCCC versions.  We
- * determine whether the workaround is actually needed the first time
- * we are invoked such that we only make the firmware call if we
- * really need to.
+ * Firmware-based workaround for CVE-2017-5715.  We determine whether
+ * the workaround is actually implemented and needed the first time we
+ * are invoked such that we only make the firmware call when appropriate.
  */
 
 void
@@ -178,14 +176,6 @@ psci_flush_bp_none(void)
 }
 
 void
-psci_flush_bp_psci_version(void)
-{
-   struct psci_softc *sc = psci_sc;
-
-   (*sc->sc_callfn)(PSCI_VERSION, 0, 0, 0);
-}
-
-void
 psci_flush_bp_smccc_arch_workaround_1(void)
 {
struct psci_softc *sc = psci_sc;
@@ -199,32 +189,17 @@ psci_flush_bp(void)
struct psci_softc *sc = psci_sc;
struct cpu_info *ci = curcpu();
 
-   /* No PSCI or an old version of PSCI; nothing we can do. */
-   if (sc == NULL || sc->sc_version < 0x1) {
-   ci->ci_flush_bp = psci_flush_bp_none;
-   return;
-   }
-
-   /*
-* PSCI 1.0 or later with SMCCC 1.0; invoke PSCI_VERSION and
-* hope for the best.
-*/
-   if (sc->sc_smccc_version < 0x10001) {
-   ci->ci_flush_bp = psci_flush_bp_psci_version;
-   ci->ci_flush_bp();
-   return;
-   }
-
/*
-* SMCCC 1.1 or later; we can actually detect if the
-* workaround is implemented and needed.
+* SMCCC 1.1 allows us to detect if the workaround is
+* implemented and needed.
 */
-   if (smccc_arch_features(SMCCC_ARCH_WORKAROUND_1) == 0) {
+   if (sc && sc->sc_smccc_version >= 0x10001 &&
+   smccc_arch_features(SMCCC_ARCH_WORKAROUND_1) == 0) {
/* Workaround implemented and needed. */
ci->ci_flush_bp = psci_flush_bp_smccc_arch_workaround_1;
ci->ci_flush_bp();
} else {
-   /* No workaround needed. */
+   /* Workaround isn't implemented or isn't needed. */
ci->ci_flush_bp = psci_flush_bp_none;
}
 }



Use console speed from device tree

2018-05-05 Thread Mark Kettenis
Diff below makes com(4) use the console speed from /chosen/stdout-path
when probided.  

stdout-path: 'serial0:115200n8'

We could also parse the partity and number of bits, but frankly that
isn't worth it.  Everybody uses 8 bits with no parity these days.
I'll make the same changes to armv7 if I get an ok for this.


Index: arch/arm64/arm64/machdep.c
===
RCS file: /cvs/src/sys/arch/arm64/arm64/machdep.c,v
retrieving revision 1.31
diff -u -p -r1.31 machdep.c
--- arch/arm64/arm64/machdep.c  29 Mar 2018 21:35:23 -  1.31
+++ arch/arm64/arm64/machdep.c  5 May 2018 11:15:06 -
@@ -56,7 +56,8 @@ uint8_t *bootmac = NULL;
 
 extern uint64_t esym;
 
-int stdout_node = 0;
+int stdout_node;
+int stdout_speed;
 
 void (*cpuresetfn)(void);
 void (*powerdownfn)(void);
@@ -150,6 +151,30 @@ inittodr(time_t base)
printf("WARNING: CHECK AND RESET THE DATE!\n");
 }
 
+static int
+atoi(const char *s)
+{
+   int n, neg;
+
+   n = 0;
+   neg = 0;
+
+   while (*s == '-') {
+   s++;
+   neg = !neg;
+   }
+
+   while (*s != '\0') {
+   if (*s < '0' || *s > '9')
+   break;
+
+   n = (10 * n) + (*s - '0');
+   s++;
+   }
+
+   return (neg ? -n : n);
+}
+
 void *
 fdt_find_cons(const char *name)
 {
@@ -165,8 +190,10 @@ fdt_find_cons(const char *name)
if (fdt_node_property(node, "stdout-path", &stdout) > 0) {
if (strchr(stdout, ':') != NULL) {
strlcpy(buf, stdout, sizeof(buf));
-   if ((p = strchr(buf, ':')) != NULL)
-   *p = '\0';
+   if ((p = strchr(buf, ':')) != NULL) {
+   *p++ = '\0';
+   stdout_speed = atoi(p);
+   }
stdout = buf;
}
if (stdout[0] != '/') {
Index: arch/arm64/dev/com_fdt.c
===
RCS file: /cvs/src/sys/arch/arm64/dev/com_fdt.c,v
retrieving revision 1.4
diff -u -p -r1.4 com_fdt.c
--- arch/arm64/dev/com_fdt.c2 Apr 2018 12:59:39 -   1.4
+++ arch/arm64/dev/com_fdt.c5 May 2018 11:15:06 -
@@ -80,7 +80,6 @@ com_fdt_init_cons(void)
if (bus_space_map(comconsiot, reg.addr, reg.size, 0, &comconsioh))
return;
 
-   comconsrate = B115200;
cn_tab = &com_fdt_cons;
 }
 
@@ -136,6 +135,7 @@ com_fdt_attach(struct device *parent, st
SET(sc->sc_hwflags, COM_HW_CONSOLE);
SET(sc->sc_swflags, COM_SW_SOFTCAR);
comconsfreq = sc->sc_frequency;
+   comconsrate = stdout_speed ? stdout_speed : B115200;
}
 
if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
Index: arch/arm64/include/fdt.h
===
RCS file: /cvs/src/sys/arch/arm64/include/fdt.h,v
retrieving revision 1.3
diff -u -p -r1.3 fdt.h
--- arch/arm64/include/fdt.h20 Mar 2018 23:04:48 -  1.3
+++ arch/arm64/include/fdt.h5 May 2018 11:15:06 -
@@ -35,6 +35,7 @@ struct fdt_attach_args {
 };
 
 extern int stdout_node;
+extern int stdout_speed;
 extern bus_space_tag_t fdt_cons_bs_tag;
 
 void *fdt_find_cons(const char *);



Fix dwge(4) on Rockchip SoCs

2018-05-05 Thread Mark Kettenis
Lost a few hairs over this one.  Turns out you have to write these
registers in the right order to program the address filter correctly.

With this diff the Gigabit Ethernet interface on the Rock64 works.

ok?


Index: dev/ic/dwc_gmac.c
===
RCS file: /cvs/src/sys/dev/ic/dwc_gmac.c,v
retrieving revision 1.9
diff -u -p -r1.9 dwc_gmac.c
--- dev/ic/dwc_gmac.c   7 Apr 2018 22:43:12 -   1.9
+++ dev/ic/dwc_gmac.c   5 May 2018 21:43:54 -
@@ -304,13 +304,13 @@ dwc_gmac_reset(struct dwc_gmac_softc *sc
 void
 dwc_gmac_write_hwaddr(struct dwc_gmac_softc *sc, uint8_t *enaddr)
 {
-   uint32_t lo, hi;
+   uint32_t hi, lo;
 
+   hi = enaddr[4] | (enaddr[5] << 8);
lo = enaddr[0] | (enaddr[1] << 8) | (enaddr[2] << 16)
| (enaddr[3] << 24);
-   hi = enaddr[4] | (enaddr[5] << 8);
-   bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0LO, lo);
bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0HI, hi);
+   bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0LO, lo);
 }
 
 int



Automatic configuration of /etc/ttys in installer

2018-05-07 Thread Mark Kettenis
After my recent changes to armv7 and arm64 the installer and
single-user mode are usable with a non-standard serial console speed.
However, the installer will still install an /etc/ttys file with
std.115200 in it.  This means that getty(8) will change the speed
which means you get garbage or nothing on your serial connections.

Here is an attempt to make the installer modify the console entry in
/etc/ttys to reflect the correct speed.  This uses some of the same
code that we use to offer i386/amd64 users to switch the console to
serial.  But it doesn't ask the question since we don't have to guess
what the console will be.  I restricted the patching to the set of
speeds that we actually support.

Is there a better way to do this?


Index: distrib/arm64/ramdisk/install.md
===
RCS file: /cvs/src/distrib/arm64/ramdisk/install.md,v
retrieving revision 1.9
diff -u -p -r1.9 install.md
--- distrib/arm64/ramdisk/install.md23 Mar 2018 05:02:27 -  1.9
+++ distrib/arm64/ramdisk/install.md8 May 2018 06:40:44 -
@@ -150,4 +150,12 @@ md_congrats() {
 }
 
 md_consoleinfo() {
+   CTTY=console
+   DEFCONS=y
+   case $CSPEED in
+   9600|19200|38400|57600|115200|150)
+   ;;
+   *)
+   CSPEED=115200;;
+   esac
 }
Index: distrib/miniroot/install.sub
===
RCS file: /cvs/src/distrib/miniroot/install.sub,v
retrieving revision 1.1067
diff -u -p -r1.1067 install.sub
--- distrib/miniroot/install.sub7 May 2018 10:44:01 -   1.1067
+++ distrib/miniroot/install.sub8 May 2018 06:40:44 -
@@ -2637,6 +2637,7 @@ apply() {
if [[ $DEFCONS == y ]]; then
cp /mnt/etc/ttys /tmp/i/ttys
sed -e "/^$CTTY/s/std.9600/std.${CSPEED}/" \
+   -e "/^$CTTY/s/std.115200/std.${CSPEED}/" \
-e "/^$CTTY/s/unknown/vt220 /" \
-e "/$CTTY/s/off.*/on secure/" /tmp/i/ttys 
>/mnt/etc/ttys
[[ -n $CPROM ]] &&



Re: Print xHCI version

2018-05-08 Thread Mark Kettenis
> Date: Tue, 8 May 2018 10:47:16 +0200
> From: Martin Pieuchot 
> 
> I'd like to print the version of the xHCI controller in the dmesg like
> we do for AHCI.  I've been looking at some xHCI 1.1 peculiarities lately
> and apparently our driver also need some love for pre 1.0 chips.
> 
> With the diff below, we will now print:
> 
> xhci0 at pci0 dev 20 function 0 "Intel 9 Series xHCI" rev 0x03: msi, xHCI 1.0
> 
> or
> 
> xhci1 at imxxhci1, xHCI 1.16
> 
> ok?

ok kettenis@

> Index: arch/armv7/marvell/mvxhci.c
> ===
> RCS file: /cvs/src/sys/arch/armv7/marvell/mvxhci.c,v
> retrieving revision 1.1
> diff -u -p -r1.1 mvxhci.c
> --- arch/armv7/marvell/mvxhci.c   24 Mar 2017 20:27:27 -  1.1
> +++ arch/armv7/marvell/mvxhci.c   8 May 2018 08:24:03 -
> @@ -149,8 +149,6 @@ mvxhci_attach(struct device *parent, str
>   goto unmap;
>   }
>  
> - printf("\n");
> -
>   strlcpy(sc->sc.sc_vendor, "Marvell", sizeof(sc->sc.sc_vendor));
>   if ((error = xhci_init(&sc->sc)) != 0) {
>   printf("%s: init failed, error=%d\n",
> Index: dev/pci/xhci_pci.c
> ===
> RCS file: /cvs/src/sys/dev/pci/xhci_pci.c,v
> retrieving revision 1.8
> diff -u -p -r1.8 xhci_pci.c
> --- dev/pci/xhci_pci.c1 Jun 2016 06:19:59 -   1.8
> +++ dev/pci/xhci_pci.c8 May 2018 08:22:07 -
> @@ -173,7 +173,7 @@ xhci_pci_attach(struct device *parent, s
>   printf("\n");
>   goto unmap_ret;
>   }
> - printf(": %s\n", intrstr);
> + printf(": %s", intrstr);
>  
>   /* Figure out vendor for root hub descriptor. */
>   vendor = pci_findvendor(pa->pa_id);
> Index: dev/usb/xhci.c
> ===
> RCS file: /cvs/src/sys/dev/usb/xhci.c,v
> retrieving revision 1.84
> diff -u -p -r1.84 xhci.c
> --- dev/usb/xhci.c29 Apr 2018 09:00:42 -  1.84
> +++ dev/usb/xhci.c8 May 2018 08:24:45 -
> @@ -286,12 +286,6 @@ xhci_init(struct xhci_softc *sc)
>   uint32_t hcr;
>   int npage, error;
>  
> -#ifdef XHCI_DEBUG
> - uint16_t vers;
> -
> - vers = XREAD2(sc, XHCI_HCIVERSION);
> - printf("%s: xHCI version %x.%x\n", DEVNAME(sc), vers >> 8, vers & 0xff);
> -#endif
>   sc->sc_bus.usbrev = USBREV_3_0;
>   sc->sc_bus.methods = &xhci_bus_methods;
>   sc->sc_bus.pipe_size = sizeof(struct xhci_pipe);
> @@ -299,6 +293,9 @@ xhci_init(struct xhci_softc *sc)
>   sc->sc_oper_off = XREAD1(sc, XHCI_CAPLENGTH);
>   sc->sc_door_off = XREAD4(sc, XHCI_DBOFF);
>   sc->sc_runt_off = XREAD4(sc, XHCI_RTSOFF);
> +
> + sc->sc_version = XREAD2(sc, XHCI_HCIVERSION);
> + printf(", xHCI %u.%u\n", sc->sc_version >> 8, sc->sc_version & 0xff);
>  
>  #ifdef XHCI_DEBUG
>   printf("%s: CAPLENGTH=%#lx\n", DEVNAME(sc), sc->sc_oper_off);
> Index: dev/usb/xhcivar.h
> ===
> RCS file: /cvs/src/sys/dev/usb/xhcivar.h,v
> retrieving revision 1.8
> diff -u -p -r1.8 xhcivar.h
> --- dev/usb/xhcivar.h 18 Jan 2015 20:35:11 -  1.8
> +++ dev/usb/xhcivar.h 8 May 2018 08:18:21 -
> @@ -91,6 +91,7 @@ struct xhci_softc {
>   bus_size_t   sc_runt_off;   /* Runtime */
>   bus_size_t   sc_door_off;   /* Doorbell  */
>  
> + uint16_t sc_version;/* xHCI version */
>   uint32_t sc_pagesize;   /* xHCI page size, minimum 4k */
>   uint32_t sc_ctxsize;/* 32/64 byte context structs */
>  
> Index: dev/fdt/xhci_fdt.c
> ===
> RCS file: /cvs/src/sys/dev/fdt/xhci_fdt.c,v
> retrieving revision 1.10
> diff -u -p -r1.10 xhci_fdt.c
> --- dev/fdt/xhci_fdt.c3 May 2018 10:57:37 -   1.10
> +++ dev/fdt/xhci_fdt.c8 May 2018 08:23:40 -
> @@ -95,8 +95,6 @@ xhci_fdt_attach(struct device *parent, s
>   goto unmap;
>   }
>  
> - printf("\n");
> -
>   /* Set up power domain */
>   power_domain_enable(sc->sc_node);
>  
> 
> 



pmap_growkernel(9) for arm64

2018-05-12 Thread Mark Kettenis
The diff below implements pmap_growkernel(9) for arm64.  The
implementation is somewhat tricky since we (deliberately) do not
implement a direct map on arm64.  To be able to map the kernel page
tables we need to reserve virtual address space because by the time
pmap_growkernel() gets called we are pretty much guaranteed that there
isn't much left.  The reservation is done through a uvm_km_suballoc()
such that we can easily use km_alloc(9) to allocate memory for the
page tables.  We avoid calling too deep into uvm by making the map
interrupt safe.

The diff also bumps up the available KVA to 4 GB (from 1.25 GB) since
doing so doesn't waste a lot of memory anymore.

Peter, I have some hope this will fix (some of) the lockups you're
seeing on the arm64 ports builders.  Could you give this a spin and
let me know about the results?


Index: arch/arm64/arm64/pmap.c
===
RCS file: /cvs/src/sys/arch/arm64/arm64/pmap.c,v
retrieving revision 1.51
diff -u -p -r1.51 pmap.c
--- arch/arm64/arm64/pmap.c 18 Apr 2018 11:41:16 -  1.51
+++ arch/arm64/arm64/pmap.c 12 May 2018 19:12:45 -
@@ -1038,6 +1038,112 @@ VP_Lx(paddr_t pa)
return pa | Lx_TYPE_PT;
 }
 
+/*
+ * Allocator for growing the kernel page tables.  We use a dedicated
+ * submap to make sure we have the space to map them as we are called
+ * when address space is tight!
+ */
+
+struct vm_map *pmap_kvp_map;
+
+const struct kmem_va_mode kv_kvp = {
+   .kv_map = &pmap_kvp_map,
+   .kv_wait = 0
+};
+
+void *
+pmap_kvp_alloc(void)
+{
+   return km_alloc(sizeof(struct pmapvp0), &kv_kvp, &kp_zero, &kd_nowait);
+}
+
+struct pte_desc *
+pmap_kpted_alloc(void)
+{
+   static struct pte_desc *pted;
+   static int npted;
+
+   if (npted == 0) {
+   pted = km_alloc(PAGE_SIZE, &kv_kvp, &kp_zero, &kd_nowait);
+   if (pted == NULL)
+   return NULL;
+   npted = PAGE_SIZE / sizeof(struct pte_desc);
+   }
+
+   npted--;
+   return pted++;
+}
+
+/*
+ * In pmap_bootstrap() we allocate the page tables for the first 512 MB
+ * of the kernel address space.
+ */
+vaddr_t pmap_maxkvaddr = VM_MIN_KERNEL_ADDRESS + 512 * 1024 * 1024;
+
+vaddr_t
+pmap_growkernel(vaddr_t maxkvaddr)
+{
+   struct pmapvp1 *vp1 = pmap_kernel()->pm_vp.l1;
+   struct pmapvp2 *vp2;
+   struct pmapvp3 *vp3;
+   struct pte_desc *pted;
+   paddr_t pa;
+   int lb_idx2, ub_idx2;
+   int i, j, k;
+
+   if (maxkvaddr <= pmap_maxkvaddr)
+   return pmap_maxkvaddr;
+
+   for (i = VP_IDX1(pmap_maxkvaddr); i <= VP_IDX1(maxkvaddr - 1); i++) {
+   vp2 = vp1->vp[i];
+   if (vp2 == NULL) {
+   vp2 = pmap_kvp_alloc();
+   if (vp2 == NULL)
+   return pmap_maxkvaddr;
+   pmap_extract(pmap_kernel(), (vaddr_t)vp2, &pa);
+   vp1->vp[i] = vp2;
+   vp1->l1[i] = VP_Lx(pa);
+   }
+
+   if (i == VP_IDX1(pmap_maxkvaddr)) {
+   lb_idx2 = VP_IDX2(pmap_maxkvaddr);
+   } else {
+   lb_idx2 = 0;
+   }
+
+   if (i == VP_IDX1(maxkvaddr - 1)) {
+   ub_idx2 = VP_IDX2(maxkvaddr - 1);
+   } else {
+   ub_idx2 = VP_IDX2_CNT - 1;
+   }
+
+   for (j = lb_idx2; j <= ub_idx2; j++) {
+   vp3 = vp2->vp[j];
+   if (vp3 == NULL) {
+   vp3 = pmap_kvp_alloc();
+   if (vp3 == NULL)
+   return pmap_maxkvaddr;
+   pmap_extract(pmap_kernel(), (vaddr_t)vp3, &pa);
+   vp2->vp[j] = vp3;
+   vp2->l2[j] = VP_Lx(pa);
+   }
+
+   for (k = 0; k <= VP_IDX3_CNT - 1; k++) {
+   if (vp3->vp[k] == NULL) {
+   pted = pmap_kpted_alloc();
+   if (pted == NULL)
+   return pmap_maxkvaddr;
+   vp3->vp[k] = pted;
+   pmap_maxkvaddr += PAGE_SIZE;
+   }
+   }
+   }
+   }
+
+   KASSERT(pmap_maxkvaddr >= maxkvaddr);
+   return pmap_maxkvaddr;
+}
+
 void pmap_setup_avail(uint64_t ram_start, uint64_t ram_end, uint64_t kvo);
 
 /*
@@ -1100,7 +1206,7 @@ pmap_bootstrap(long kvo, paddr_t lpt1, l
 
/* allocate Lx entries */
for (i = VP_IDX1(VM_MIN_KERNEL_ADDRESS);
-   i <= VP_IDX1(VM_MAX_KERNEL_ADDRESS);
+   i <= VP_IDX1(pmap_maxkvaddr - 1);
i++) {
mappings_allo

acpi(4): GenericSerialBus OperationRegion support

2018-05-13 Thread Mark Kettenis
The diff below implements functionality that allows AML access to
devices that sit on an I2C bus.  Only a subset of the various access
methods is implemented; some of the missing ones are not a very good
fit for our AML implementation.  But this is enough to make reading
the battery status on the little Lenovo that mlarkin@ handed me at Elk
Lakes work.

Probably needs some wider testing.

After that's done, ok?


Index: dev/acpi/acpi.c
===
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.341
diff -u -p -r1.341 acpi.c
--- dev/acpi/acpi.c 27 Mar 2018 21:11:16 -  1.341
+++ dev/acpi/acpi.c 13 May 2018 13:49:46 -
@@ -920,6 +920,23 @@ acpi_register_gpio(struct acpi_softc *sc
 }
 
 void
+acpi_register_gsb(struct acpi_softc *sc, struct aml_node *devnode)
+{
+   struct aml_value arg[2];
+   struct aml_node *node;
+
+   /* Register GenericSerialBus address space. */
+   memset(&arg, 0, sizeof(arg));
+   arg[0].type = AML_OBJTYPE_INTEGER;
+   arg[0].v_integer = ACPI_OPREG_GSB;
+   arg[1].type = AML_OBJTYPE_INTEGER;
+   arg[1].v_integer = 1;
+   node = aml_searchname(devnode, "_REG");
+   if (node && aml_evalnode(sc, node, 2, arg, NULL))
+   printf("%s: _REG failed\n", node->name);
+}
+
+void
 acpi_attach(struct device *parent, struct device *self, void *aux)
 {
struct bios_attach_args *ba = aux;
Index: dev/acpi/acpivar.h
===
RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.89
diff -u -p -r1.89 acpivar.h
--- dev/acpi/acpivar.h  29 Nov 2017 22:51:01 -  1.89
+++ dev/acpi/acpivar.h  13 May 2018 13:49:46 -
@@ -333,6 +333,7 @@ void acpi_wakeup(void *);
 int acpi_gasio(struct acpi_softc *, int, int, uint64_t, int, int, void *);
 
 void   acpi_register_gpio(struct acpi_softc *, struct aml_node *);
+void   acpi_register_gsb(struct acpi_softc *, struct aml_node *);
 
 intacpi_set_gpehandler(struct acpi_softc *, int,
int (*)(struct acpi_softc *, int, void *), void *, int);
Index: dev/acpi/amltypes.h
===
RCS file: /cvs/src/sys/dev/acpi/amltypes.h,v
retrieving revision 1.45
diff -u -p -r1.45 amltypes.h
--- dev/acpi/amltypes.h 8 May 2016 11:08:01 -   1.45
+++ dev/acpi/amltypes.h 13 May 2018 13:49:46 -
@@ -371,6 +371,8 @@ struct acpi_gpio {
void(*intr_establish)(void *, int, int, int (*)(void *), void *);
 };
 
+struct i2c_controller;
+
 struct aml_node {
struct aml_node *parent;
 
@@ -385,8 +387,9 @@ struct aml_node {
u_int8_t*end;
 
struct aml_value *value;
-   struct acpi_pci  *pci;
+   struct acpi_pci *pci;
struct acpi_gpio *gpio;
+   struct i2c_controller *i2c;
 };
 
 #define aml_bitmask(n) (1L << ((n) & 0x7))
Index: dev/acpi/dsdt.c
===
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.236
diff -u -p -r1.236 dsdt.c
--- dev/acpi/dsdt.c 29 Nov 2017 15:22:22 -  1.236
+++ dev/acpi/dsdt.c 13 May 2018 13:49:47 -
@@ -33,6 +33,8 @@
 #include 
 #include 
 
+#include 
+
 #ifdef SMALL_KERNEL
 #undef ACPI_DEBUG
 #endif
@@ -2288,6 +2290,7 @@ aml_register_regionspace(struct aml_node
 
 void aml_rwgen(struct aml_value *, int, int, struct aml_value *, int, int);
 void aml_rwgpio(struct aml_value *, int, int, struct aml_value *, int, int);
+void aml_rwgsb(struct aml_value *, int, int, struct aml_value *, int, int);
 void aml_rwindexfield(struct aml_value *, struct aml_value *val, int);
 void aml_rwfield(struct aml_value *, int, int, struct aml_value *, int);
 
@@ -2512,6 +2515,96 @@ aml_rwgpio(struct aml_value *conn, int b
 }
 
 void
+aml_rwgsb(struct aml_value *conn, int bpos, int blen, struct aml_value *val,
+int mode, int flag)
+{
+   union acpi_resource *crs = (union acpi_resource *)conn->v_buffer;
+   struct aml_node *node;
+   i2c_tag_t tag;
+   i2c_op_t op;
+   i2c_addr_t addr;
+   int cmdlen, buflen;
+   uint8_t cmd;
+   uint8_t *buf;
+   int err;
+
+   if (conn->type != AML_OBJTYPE_BUFFER || conn->length < 5 ||
+   AML_CRSTYPE(crs) != LR_SERBUS || AML_CRSLEN(crs) > conn->length ||
+   crs->lr_i2cbus.revid != 1 || crs->lr_i2cbus.type != LR_SERBUS_I2C)
+   aml_die("Invalid GenericSerialBus");
+   if (AML_FIELD_ACCESS(flag) != AML_FIELD_BUFFERACC ||
+   bpos & 0x3 || blen != 8)
+   aml_die("Invalid GenericSerialBus access");
+
+   node = aml_searchname(conn->node,
+   (char *)&crs->lr_i2cbus.vdata[crs->lr_i2cbus.tlength - 6]);
+
+   if (node == NULL || node->i2c == NULL)
+   aml_die("Could not find GenericSerialBus controller");
+
+   switch (((flag >> 6) & 0x3)) {
+   case 0: /* Normal */

com(4) console register width/shift support

2018-05-13 Thread Mark Kettenis
The diff below extends the register width/shift support in com(4) such
that the serial console on armv7 and arm64 doesn't have to use the
nasty bus space hacks anymore.  I removed the com_common_getc() and
com_common_putc() functions as they didn't really serve any purpose
anymore.  The equivalent code is now simply part of comcngetc() and
comcnputc().

ok?


Index: arch/arm64/dev/com_fdt.c
===
RCS file: /cvs/src/sys/arch/arm64/dev/com_fdt.c,v
retrieving revision 1.5
diff -u -p -r1.5 com_fdt.c
--- arch/arm64/dev/com_fdt.c6 May 2018 17:16:48 -   1.5
+++ arch/arm64/dev/com_fdt.c13 May 2018 21:04:41 -
@@ -28,8 +28,6 @@
 #include 
 #include 
 
-#include 
-
 #include 
 #include 
 #include 
@@ -45,12 +43,8 @@ struct cfattach com_fdt_ca = {
sizeof (struct com_softc), com_fdt_match, com_fdt_attach
 };
 
-int com_fdt_cngetc(dev_t);
-void com_fdt_cnputc(dev_t, int);
-void com_fdt_cnpollc(dev_t, int);
-
 struct consdev com_fdt_cons = {
-   NULL, NULL, com_fdt_cngetc, com_fdt_cnputc, com_fdt_cnpollc, NULL,
+   NULL, NULL, comcngetc, comcnputc, comcnpollc, NULL,
NODEV, CN_LOWPRI
 };
 
@@ -76,7 +70,10 @@ com_fdt_init_cons(void)
 * comcnattach() does by doing the minimal setup here.
 */
 
-   comconsiot = &arm64_a4x_bs_tag;
+   comcons_reg_width = OF_getpropint(stdout_node, "reg-io-width", 4);
+   comcons_reg_shift = OF_getpropint(stdout_node, "reg-shift", 2);
+
+   comconsiot = fdt_cons_bs_tag;
if (bus_space_map(comconsiot, reg.addr, reg.size, 0, &comconsioh))
return;
 
@@ -160,21 +157,4 @@ com_fdt_intr_designware(void *cookie)
com_read_reg(sc, com_usr);
 
return comintr(sc);
-}
-
-int
-com_fdt_cngetc(dev_t dev)
-{
-   return com_common_getc(comconsiot, comconsioh);
-}
-
-void
-com_fdt_cnputc(dev_t dev, int c)
-{
-   com_common_putc(comconsiot, comconsioh, c);
-}
-
-void
-com_fdt_cnpollc(dev_t dev, int on)
-{
 }
Index: arch/armv7/dev/com_fdt.c
===
RCS file: /cvs/src/sys/arch/armv7/dev/com_fdt.c,v
retrieving revision 1.12
diff -u -p -r1.12 com_fdt.c
--- arch/armv7/dev/com_fdt.c7 May 2018 14:13:54 -   1.12
+++ arch/armv7/dev/com_fdt.c13 May 2018 21:04:41 -
@@ -28,9 +28,6 @@
 #include 
 #include 
 
-/* pick up armv7_a4x_bs_tag */
-#include 
-
 #include 
 #include 
 #include 
@@ -49,12 +46,8 @@ struct cfattach com_fdt_ca = {
sizeof (struct com_softc), com_fdt_match, com_fdt_attach
 };
 
-int com_fdt_cngetc(dev_t);
-void com_fdt_cnputc(dev_t, int);
-void com_fdt_cnpollc(dev_t, int);
-
 struct consdev com_fdt_cons = {
-   NULL, NULL, com_fdt_cngetc, com_fdt_cnputc, com_fdt_cnpollc, NULL,
+   NULL, NULL, comcngetc, comcnputc, comcnpollc, NULL,
NODEV, CN_LOWPRI
 };
 
@@ -80,7 +73,10 @@ com_fdt_init_cons(void)
 * comcnattach() does by doing the minimal setup here.
 */
 
-   comconsiot = &armv7_a4x_bs_tag;
+   comcons_reg_width = OF_getpropint(stdout_node, "reg-io-width", 4);
+   comcons_reg_shift = OF_getpropint(stdout_node, "reg-shift", 2);
+
+   comconsiot = fdt_cons_bs_tag;
if (bus_space_map(comconsiot, reg.addr, reg.size, 0, &comconsioh))
return;
 
@@ -165,21 +161,4 @@ com_fdt_intr_designware(void *cookie)
com_read_reg(sc, com_usr);
 
return comintr(sc);
-}
-
-int
-com_fdt_cngetc(dev_t dev)
-{
-   return com_common_getc(comconsiot, comconsioh);
-}
-
-void
-com_fdt_cnputc(dev_t dev, int c)
-{
-   com_common_putc(comconsiot, comconsioh, c);
-}
-
-void
-com_fdt_cnpollc(dev_t dev, int on)
-{
 }
Index: dev/ic/com.c
===
RCS file: /cvs/src/sys/dev/ic/com.c,v
retrieving revision 1.168
diff -u -p -r1.168 com.c
--- dev/ic/com.c2 May 2018 13:20:12 -   1.168
+++ dev/ic/com.c13 May 2018 21:04:42 -
@@ -1133,52 +1133,6 @@ comintr(void *arg)
}
 }
 
-/*
- * The following functions are polled getc and putc routines, used
- * by the console glue.
- */
-
-int
-com_common_getc(bus_space_tag_t iot, bus_space_handle_t ioh)
-{
-   int s = splhigh();
-   u_char stat, c;
-
-   /* Block until a character becomes available. */
-   while (!ISSET(stat = bus_space_read_1(iot, ioh, com_lsr), LSR_RXRDY))
-   continue;
-
-   c = bus_space_read_1(iot, ioh, com_data);
-
-   /* Clear any interrupts generated by this transmission. */
-   stat = bus_space_read_1(iot, ioh, com_iir);
-   splx(s);
-   return (c);
-}
-
-void
-com_common_putc(bus_space_tag_t iot, bus_space_handle_t ioh, int c)
-{
-   int s = spltty();
-   int timo;
-
-   /* Wait for any pending transmission to finish. */
-   timo = 2000;
-   while (!ISSET(bus_space_read_1(iot, ioh, com_lsr), LSR_TXRDY) && --timo)
-   delay(1);
-
-   bus_space_write_1(i

Re: acpi(4): GenericSerialBus OperationRegion support

2018-05-14 Thread Mark Kettenis
> Date: Sun, 13 May 2018 22:27:09 -0700
> From: Mike Larkin 
> 
> On Sun, May 13, 2018 at 03:57:50PM +0200, Mark Kettenis wrote:
> > The diff below implements functionality that allows AML access to
> > devices that sit on an I2C bus.  Only a subset of the various access
> > methods is implemented; some of the missing ones are not a very good
> > fit for our AML implementation.  But this is enough to make reading
> > the battery status on the little Lenovo that mlarkin@ handed me at Elk
> > Lakes work.
> > 
> 
> Can you elaborate on what isn't a good fit? Just curious.

Our i2c layer makes implementing the "Block" access types awkward, at
least for reads.  At least it isn't obvious to me what implementation
would work.

The AML interpreter makes implementing the "ProcessCall" interfaces
hard at least for reads as in that case the code doesn't see the
buffer that contains the values that have to be written.

We can probably find a way to make this work, but I don't seem to have
any devices that use these access types.

BTW, this stuff is important for the "suspend to idle" (S0ix) stuff.
Most platforms supporting S0ix have some sort of Power Management IC
(PMIC) ooked up over I2C that is involved in powering stuff down for
the deepest idle states.

> > Probably needs some wider testing.
> > 
> > After that's done, ok?
> > 
> > 
> > Index: dev/acpi/acpi.c
> > ===
> > RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
> > retrieving revision 1.341
> > diff -u -p -r1.341 acpi.c
> > --- dev/acpi/acpi.c 27 Mar 2018 21:11:16 -  1.341
> > +++ dev/acpi/acpi.c 13 May 2018 13:49:46 -
> > @@ -920,6 +920,23 @@ acpi_register_gpio(struct acpi_softc *sc
> >  }
> >  
> >  void
> > +acpi_register_gsb(struct acpi_softc *sc, struct aml_node *devnode)
> > +{
> > +   struct aml_value arg[2];
> > +   struct aml_node *node;
> > +
> > +   /* Register GenericSerialBus address space. */
> > +   memset(&arg, 0, sizeof(arg));
> > +   arg[0].type = AML_OBJTYPE_INTEGER;
> > +   arg[0].v_integer = ACPI_OPREG_GSB;
> > +   arg[1].type = AML_OBJTYPE_INTEGER;
> > +   arg[1].v_integer = 1;
> > +   node = aml_searchname(devnode, "_REG");
> > +   if (node && aml_evalnode(sc, node, 2, arg, NULL))
> > +   printf("%s: _REG failed\n", node->name);
> > +}
> > +
> > +void
> >  acpi_attach(struct device *parent, struct device *self, void *aux)
> >  {
> > struct bios_attach_args *ba = aux;
> > Index: dev/acpi/acpivar.h
> > ===
> > RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
> > retrieving revision 1.89
> > diff -u -p -r1.89 acpivar.h
> > --- dev/acpi/acpivar.h  29 Nov 2017 22:51:01 -  1.89
> > +++ dev/acpi/acpivar.h  13 May 2018 13:49:46 -
> > @@ -333,6 +333,7 @@ void acpi_wakeup(void *);
> >  int acpi_gasio(struct acpi_softc *, int, int, uint64_t, int, int, void *);
> >  
> >  void   acpi_register_gpio(struct acpi_softc *, struct aml_node *);
> > +void   acpi_register_gsb(struct acpi_softc *, struct aml_node *);
> >  
> >  intacpi_set_gpehandler(struct acpi_softc *, int,
> > int (*)(struct acpi_softc *, int, void *), void *, int);
> > Index: dev/acpi/amltypes.h
> > ===
> > RCS file: /cvs/src/sys/dev/acpi/amltypes.h,v
> > retrieving revision 1.45
> > diff -u -p -r1.45 amltypes.h
> > --- dev/acpi/amltypes.h 8 May 2016 11:08:01 -   1.45
> > +++ dev/acpi/amltypes.h 13 May 2018 13:49:46 -
> > @@ -371,6 +371,8 @@ struct acpi_gpio {
> > void(*intr_establish)(void *, int, int, int (*)(void *), void *);
> >  };
> >  
> > +struct i2c_controller;
> > +
> >  struct aml_node {
> > struct aml_node *parent;
> >  
> > @@ -385,8 +387,9 @@ struct aml_node {
> > u_int8_t*end;
> >  
> > struct aml_value *value;
> > -   struct acpi_pci  *pci;
> > +   struct acpi_pci *pci;
> > struct acpi_gpio *gpio;
> > +   struct i2c_controller *i2c;
> >  };
> >  
> >  #define aml_bitmask(n) (1L << ((n) & 0x7))
> > Index: dev/acpi/dsdt.c
> > ===
> > RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
> > retrieving revision 1.236
> > diff -u -p -r1.236 dsdt.c
> > --- dev/ac

Drop memory barriers from _aromic_lock() on armv7 and arm64

2018-05-14 Thread Mark Kettenis
Since the callers now add the barriers we can drop them here.

ok?


Index: lib/libc/arch/aarch64/gen/_atomic_lock.c
===
RCS file: /cvs/src/lib/libc/arch/aarch64/gen/_atomic_lock.c,v
retrieving revision 1.1
diff -u -p -r1.1 _atomic_lock.c
--- lib/libc/arch/aarch64/gen/_atomic_lock.c15 Aug 2017 06:16:37 -  
1.1
+++ lib/libc/arch/aarch64/gen/_atomic_lock.c14 May 2018 18:34:02 -
@@ -41,7 +41,6 @@ _atomic_lock(volatile _atomic_lock_t *lo
"   stlxr %w2, %w3, [%x1]  \n"
"   cmp %w2, #0\n"
"   bne 1b \n"
-   "   dmb sy \n"
: "+r" (old), "+r" (lock), "+r" (scratch)
: "r" (_ATOMIC_LOCK_LOCKED));
 
Index: lib/libc/arch/arm/gen/_atomic_lock.c
===
RCS file: /cvs/src/lib/libc/arch/arm/gen/_atomic_lock.c,v
retrieving revision 1.1
diff -u -p -r1.1 _atomic_lock.c
--- lib/libc/arch/arm/gen/_atomic_lock.c15 Aug 2017 06:13:24 -  
1.1
+++ lib/libc/arch/arm/gen/_atomic_lock.c14 May 2018 18:34:02 -
@@ -41,7 +41,6 @@ _atomic_lock(volatile _atomic_lock_t *lo
"   strex %2, %3, [%1]  \n"
"   cmp %2, #0  \n"
"   bne 1b  \n"
-   "   dmb sy  \n"
: "+r" (old), "+r" (lock), "+r" (scratch)
: "r" (_ATOMIC_LOCK_LOCKED));
 



Remove unused arm64 pmap_steal_memory() implementation

2018-05-14 Thread Mark Kettenis
This code won't work and I think implementing it only makes sense for
architectures that have a direct map.

ok?


Index: arch/arm64/arm64/pmap.c
===
RCS file: /cvs/src/sys/arch/arm64/arm64/pmap.c,v
retrieving revision 1.51
diff -u -p -r1.51 pmap.c
--- arch/arm64/arm64/pmap.c 18 Apr 2018 11:41:16 -  1.51
+++ arch/arm64/arm64/pmap.c 14 May 2018 18:38:54 -
@@ -960,72 +960,6 @@ pmap_vp_destroy(pmap_t pm)
pm->pm_vp.l0 = NULL;
 }
 
-/*
- * Similar to pmap_steal_avail, but operating on vm_physmem since
- * uvm_page_physload() has been called.
- */
-vaddr_t
-pmap_steal_memory(vsize_t size, vaddr_t *start, vaddr_t *end)
-{
-   struct vm_physseg *seg;
-   vaddr_t va;
-   paddr_t pa;
-   int segno;
-   u_int npg;
-
-   size = round_page(size);
-   npg = atop(size);
-
-   for (segno = 0, seg = vm_physmem; segno < vm_nphysseg; segno++, seg++) {
-   if (seg->avail_end - seg->avail_start < npg)
-   continue;
-   /*
-* We can only steal at an ``unused'' segment boundary,
-* i.e. either at the start or at the end.
-*/
-   if (seg->avail_start == seg->start ||
-   seg->avail_end == seg->end)
-   break;
-   }
-   if (segno == vm_nphysseg)
-   va = 0;
-   else {
-   if (seg->avail_start == seg->start) {
-   pa = ptoa(seg->avail_start);
-   seg->avail_start += npg;
-   seg->start += npg;
-   } else {
-   pa = ptoa(seg->avail_end) - size;
-   seg->avail_end -= npg;
-   seg->end -= npg;
-   }
-   /*
-* If all the segment has been consumed now, remove it.
-* Note that the crash dump code still knows about it
-* and will dump it correctly.
-*/
-   if (seg->start == seg->end) {
-   if (vm_nphysseg-- == 1)
-   panic("pmap_steal_memory: out of memory");
-   while (segno < vm_nphysseg) {
-   seg[0] = seg[1]; /* struct copy */
-   seg++;
-   segno++;
-   }
-   }
-
-   va = (vaddr_t)pa;   /* 1:1 mapping */
-   bzero((void *)va, size);
-   }
-
-   if (start != NULL)
-   *start = VM_MIN_KERNEL_ADDRESS;
-   if (end != NULL)
-   *end = VM_MAX_KERNEL_ADDRESS;
-
-   return (va);
-}
-
 vaddr_t virtual_avail, virtual_end;
 
 static inline uint64_t



Remove a4x bus space hack on arm64

2018-05-14 Thread Mark Kettenis
No longer needed.

ok?


Index: arch/arm64/arm64/arm64var.h
===
RCS file: /cvs/src/sys/arch/arm64/arm64/arm64var.h,v
retrieving revision 1.1
diff -u -p -r1.1 arm64var.h
--- arch/arm64/arm64/arm64var.h 17 Dec 2016 23:38:33 -  1.1
+++ arch/arm64/arm64/arm64var.h 14 May 2018 21:05:45 -
@@ -20,7 +20,6 @@
 #define __ARM64VAR_H__
 
 extern bus_space_t arm64_bs_tag;
-extern bus_space_t arm64_a4x_bs_tag;
 
 #endif /* __ARM64VAR_H__ */
 
Index: arch/arm64/arm64/machdep.c
===
RCS file: /cvs/src/sys/arch/arm64/arm64/machdep.c,v
retrieving revision 1.32
diff -u -p -r1.32 machdep.c
--- arch/arm64/arm64/machdep.c  6 May 2018 17:16:48 -   1.32
+++ arch/arm64/arm64/machdep.c  14 May 2018 21:05:45 -
@@ -795,8 +795,6 @@ initarm(struct arm64_bootparams *abp)
EFI_PHYSICAL_ADDRESS system_table = 0;
int (*map_func_save)(bus_space_tag_t, bus_addr_t, bus_size_t, int,
bus_space_handle_t *);
-   int (*map_a4x_func_save)(bus_space_tag_t, bus_addr_t, bus_size_t, int,
-   bus_space_handle_t *);
 
// NOTE that 1GB of ram is mapped in by default in
// the bootstrap memory config, so nothing is necessary
@@ -947,16 +945,12 @@ initarm(struct arm64_bootparams *abp)
bus_size_t size, int flags, bus_space_handle_t *bshp);
 
map_func_save = arm64_bs_tag._space_map;
-   map_a4x_func_save = arm64_a4x_bs_tag._space_map;
-
arm64_bs_tag._space_map = pmap_bootstrap_bs_map;
-   arm64_a4x_bs_tag._space_map = pmap_bootstrap_bs_map;
 
// cninit
consinit();
 
arm64_bs_tag._space_map = map_func_save;
-   arm64_a4x_bs_tag._space_map = map_a4x_func_save;
 
/* Remap EFI runtime. */
if (mmap_start != 0 && system_table != 0)
Index: arch/arm64/dev/arm64_bus_space.c
===
RCS file: /cvs/src/sys/arch/arm64/dev/arm64_bus_space.c,v
retrieving revision 1.5
diff -u -p -r1.5 arm64_bus_space.c
--- arch/arm64/dev/arm64_bus_space.c20 Mar 2018 23:04:48 -  1.5
+++ arch/arm64/dev/arm64_bus_space.c14 May 2018 21:05:45 -
@@ -60,29 +60,6 @@ bus_space_t arm64_bs_tag = {
 };
 bus_space_t *fdt_cons_bs_tag = &arm64_bs_tag;
 
-bus_space_t arm64_a4x_bs_tag = {
-   .bus_base = 0ULL, // XXX
-   .bus_private = NULL,
-   ._space_read_1 =a4x_space_read_1,
-   ._space_write_1 =   a4x_space_write_1,
-   ._space_read_2 =a4x_space_read_2,
-   ._space_write_2 =   a4x_space_write_2,
-   ._space_read_4 =a4x_space_read_4,
-   ._space_write_4 =   a4x_space_write_4,
-   ._space_read_8 =a4x_space_read_8,
-   ._space_write_8 =   a4x_space_write_8,
-   ._space_read_raw_2 =a4x_space_read_raw_2,
-   ._space_write_raw_2 =   a4x_space_write_raw_2,
-   ._space_read_raw_4 =a4x_space_read_raw_4,
-   ._space_write_raw_4 =   a4x_space_write_raw_4,
-   ._space_read_raw_8 =a4x_space_read_raw_8,
-   ._space_write_raw_8 =   a4x_space_write_raw_8,
-   ._space_map =   generic_space_map,
-   ._space_unmap = generic_space_unmap,
-   ._space_subregion = generic_space_region,
-   ._space_vaddr = generic_space_vaddr
-};
-
 uint8_t
 generic_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
 {
@@ -258,128 +235,4 @@ void *
 generic_space_vaddr(bus_space_tag_t t, bus_space_handle_t h)
 {
return (void *)h;
-}
-
-uint8_t
-a4x_space_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
-{
-   return *(volatile uint32_t *)(h + (o*4));
-}
-
-uint16_t
-a4x_space_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
-{
-   return *(volatile uint32_t *)(h + (o*4));
-}
-
-uint32_t
-a4x_space_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
-{
-   return *(volatile uint32_t *)(h + (o*4));
-}
-
-uint64_t
-a4x_space_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o)
-{
-   return *(volatile uint64_t *)(h + (o*4));
-}
-
-void
-a4x_space_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
-uint8_t v)
-{
-   *(volatile uint32_t *)(h + (o*4)) = v;
-}
-
-void
-a4x_space_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
-uint16_t v)
-{
-   *(volatile uint32_t *)(h + (o*4)) = v;
-}
-
-void
-a4x_space_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
-uint32_t v)
-{
-   *(volatile uint32_t *)(h + (o*4)) = v;
-}
-
-void
-a4x_space_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
-uint64_t v)
-{
-   *(volatile uint64_t *)(h + (o*4)) = v;
-}
-
-void
-a4x_space_read_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o,
-uint8_t *buf, bus_size_t len)
-{
-   volatile uint16_t *addr = (volatile uint16_t *)(h + (o*4));
-   len >>= 1;
-   w

Remove a4x bus space hack on armv7

2018-05-14 Thread Mark Kettenis
No longer needed on armv7 either.

ok?


Index: arch/arm/armv7/armv7_a4x_io.S
===
RCS file: arch/arm/armv7/armv7_a4x_io.S
diff -N arch/arm/armv7/armv7_a4x_io.S
--- arch/arm/armv7/armv7_a4x_io.S   27 Apr 2017 10:57:05 -  1.2
+++ /dev/null   1 Jan 1970 00:00:00 -
@@ -1,102 +0,0 @@
-/* $OpenBSD: armv7_a4x_io.S,v 1.2 2017/04/27 10:57:05 kettenis Exp $ */
-/* $NetBSD: pxa2x0_a4x_io.S,v 1.1 2002/10/19 19:31:39 bsh Exp $ */
-
-/*
- * Copyright (c) 2002  Genetec Corporation.  All rights reserved.
- * Written by Hiroyuki Bessho for Genetec Corporation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *notice, this list of conditions and the following disclaimer in the
- *documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Genetec Corporation.
- * 4. The name of Genetec Corporation may not be used to endorse or 
- *promote products derived from this software without specific prior
- *written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/* 
- * There are simple bus space functions for IO registers mapped at
- * 32-bit aligned positions.  offset is multiplied by 4.  
- */
-
-#include 
-
-/*
- * bus_space I/O functions with offset*4
- */
-
-/*
- * read single
- */
-
-ENTRY(a4x_bs_r_1)
-   ldr r0, [r1, r2, LSL #2]
-   mov pc, lr
-
-ENTRY(a4x_bs_r_2)
-   ldr r0, [r1, r2, LSL #2]
-   mov pc, lr
-
-ENTRY(a4x_bs_r_4)
-   ldr r0, [r1, r2, LSL #2]
-   mov pc, lr
-
-/*
- * write single
- */
-
-ENTRY(a4x_bs_w_1)
-   str r3, [r1, r2, LSL #2]
-   mov pc, lr
-
-ENTRY(a4x_bs_w_2)
-   str r3, [r1, r2, LSL #2]
-   mov pc, lr
-
-ENTRY(a4x_bs_w_4)
-   str r3, [r1, r2, LSL #2]
-   mov pc, lr
-
-/*
- * read multiple
- */
-ENTRY(a4x_bs_rm_1)
-   mov r2, r2, LSL #2
-   b generic_bs_rm_1
-   
-ENTRY(a4x_bs_rm_2)
-   mov r2, r2, LSL #2
-   b generic_armv4_bs_rm_2
-
-
-
-/*
- * write multiple
- */
-ENTRY(a4x_bs_wm_1)
-   mov r2, r2, LSL #2
-   b generic_bs_wm_1
-   
-ENTRY(a4x_bs_wm_2)
-   mov r2, r2, LSL #2
-   b generic_armv4_bs_wm_2
Index: arch/arm/armv7/armv7_a4x_space.c
===
RCS file: arch/arm/armv7/armv7_a4x_space.c
diff -N arch/arm/armv7/armv7_a4x_space.c
--- arch/arm/armv7/armv7_a4x_space.c5 Dec 2012 23:20:11 -   1.2
+++ /dev/null   1 Jan 1970 00:00:00 -
@@ -1,134 +0,0 @@
-/* $OpenBSD: armv7_a4x_space.c,v 1.2 2012/12/05 23:20:11 deraadt Exp $ */
-/* $NetBSD: armv7_a4x_space.c,v 1.2 2003/07/15 00:24:54 lukem Exp $ */
-
-/*
- * Copyright (c) 2002  Genetec Corporation.  All rights reserved.
- * Written by Hiroyuki Bessho for Genetec Corporation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *notice, this list of conditions and the following disclaimer in the
- *documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *must display the following acknowledgement:
- * This product includes software developed for the NetBSD Project by
- * Genetec Corporation.
- * 4. The name of Genetec Corporation may not be used to endorse or 
- *promote products derived from this software without specific prior
- *written

ld.so arm64 syscalls

2018-05-15 Thread Mark Kettenis
There's a subtle bug in the DL_SYSCALL() implementation on arm64.
Upon error we're supposed to return -errno.  The code does a negate of
the lower 32-bit bits.  This means that syscalls that return a 64-bit
number (i.e. ssize_t) still return a positive number as the upper 32
bits remain zero.  So we should negate the full 64 bits.  That's safe
even for system calls that return a 32-bit number since setting the
lower 32 bits zeroes the upper 32 bits on arm64 just like on amd64.

Fixes a crash I saw during ports building where dl_readlink()
returning EINVAL resulted in an out-of-bounds access.

ok?


Index: libexec/ld.so/aarch64/SYS.h
===
RCS file: /cvs/src/libexec/ld.so/aarch64/SYS.h,v
retrieving revision 1.1
diff -u -p -r1.1 SYS.h
--- libexec/ld.so/aarch64/SYS.h 27 Aug 2017 21:59:51 -  1.1
+++ libexec/ld.so/aarch64/SYS.h 15 May 2018 18:13:42 -
@@ -42,5 +42,5 @@ __CONCAT(_dl_,n): ;\
ret
 
 .L_cerr:
-   neg w0, w0  /* r0 = -errno */
+   neg x0, x0  /* r0 = -errno */
ret



Implement LoadTable() in our AML interpreter

2018-05-16 Thread Mark Kettenis
Diff below implements LoadTable().  The implementation is somewhat
incomplete and will error out if the RootPathString or
ParameterPathString arguments are given.  It is not entirely clear
what we should do in that case and I aven't seen a machine that
actually specifies those arguments.  I propose we worry about that
case when we actually encounter an implementation that provides these.

This makes machines like the Dell PowerEdge R640 and R740xd work.

ok?


Index: dev/acpi/dsdt.c
===
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.236
diff -u -p -r1.236 dsdt.c
--- dev/acpi/dsdt.c 29 Nov 2017 15:22:22 -  1.236
+++ dev/acpi/dsdt.c 16 May 2018 20:22:32 -
@@ -46,6 +46,9 @@
 #define AML_INTSTRLEN  16
 #define AML_NAMESEG_LEN4
 
+struct aml_value   *aml_loadtable(struct acpi_softc *, const char *,
+   const char *, const char *, const char *,
+   const char *, struct aml_value *);
 struct aml_scope   *aml_load(struct acpi_softc *, struct aml_scope *,
struct aml_value *, struct aml_value *);
 
@@ -3530,6 +3533,37 @@ aml_seterror(struct aml_scope *scope, co
return aml_allocvalue(AML_OBJTYPE_INTEGER, 0, 0);
 }
 
+struct aml_value *
+aml_loadtable(struct acpi_softc *sc, const char *signature,
+ const char *oemid, const char *oemtableid, const char *rootpath,
+ const char *parameterpath, struct aml_value *parameterdata)
+{
+   struct acpi_table_header *hdr;
+   struct acpi_dsdt *p_dsdt;
+   struct acpi_q *entry;
+
+   if (strlen(rootpath) > 0)
+   aml_die("LoadTable: RootPathString unsupported");
+   if (strlen(parameterpath) > 0)
+   aml_die("LoadTable: ParameterPathString unsupported");
+
+   SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) {
+   hdr = entry->q_table;
+   if (strncmp(hdr->signature, signature,
+   sizeof(hdr->signature)) == 0 &&
+   strncmp(hdr->oemid, oemid, sizeof(hdr->oemid)) == 0 &&
+   strncmp(hdr->oemtableid, oemtableid,
+   sizeof(hdr->oemtableid)) == 0) {
+   p_dsdt = entry->q_table;
+   acpi_parse_aml(sc, p_dsdt->aml, p_dsdt->hdr_length -
+   sizeof(p_dsdt->hdr));
+   return aml_allocvalue(AML_OBJTYPE_DDBHANDLE, 0, 0);
+   }
+   }
+
+   return aml_allocvalue(AML_OBJTYPE_INTEGER, 0, 0);
+}
+
 /* Load new SSDT scope from memory address */
 struct aml_scope *
 aml_load(struct acpi_softc *sc, struct aml_scope *scope,
@@ -4191,7 +4225,9 @@ aml_parse(struct aml_scope *scope, int r
case AMLOP_LOADTABLE:
/* LoadTable(Sig:Str, OEMID:Str, OEMTable:Str, [RootPath:Str], 
[ParmPath:Str],
   [ParmData:DataRefObj]) => DDBHandle */
-   aml_die("LoadTable");
+   my_ret = aml_loadtable(acpi_softc, opargs[0]->v_string,
+   opargs[1]->v_string, opargs[2]->v_string,
+   opargs[3]->v_string, opargs[4]->v_string, opargs[5]);
break;
case AMLOP_LOAD:
/* Load(Object:NameString, DDBHandle:SuperName) */



Fix acpi(4) GeneralSerialBus implementation

2018-05-18 Thread Mark Kettenis
Turns out there is an alternate way to encode
AttribBytes/AttribRawBytes (and AttribRawProcessBytes) that I didn't
implement.  In fact our parsing of fields has always been wrong when
this alternative encoding is present.  But for some reason we lucked
out the parser didn't go fully off the rails.

Diff below fixes this issue and makes the battery status on my Asus
Transformerr Book T100HA work.

ok?


Index: dev/acpi/dsdt.c
===
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.238
diff -u -p -r1.238 dsdt.c
--- dev/acpi/dsdt.c 17 May 2018 20:21:15 -  1.238
+++ dev/acpi/dsdt.c 18 May 2018 18:51:36 -
@@ -2293,7 +2293,7 @@ aml_register_regionspace(struct aml_node
 
 void aml_rwgen(struct aml_value *, int, int, struct aml_value *, int, int);
 void aml_rwgpio(struct aml_value *, int, int, struct aml_value *, int, int);
-void aml_rwgsb(struct aml_value *, int, int, struct aml_value *, int, int);
+void aml_rwgsb(struct aml_value *, int, int, int, struct aml_value *, int, 
int);
 void aml_rwindexfield(struct aml_value *, struct aml_value *val, int);
 void aml_rwfield(struct aml_value *, int, int, struct aml_value *, int);
 
@@ -2518,8 +2518,8 @@ aml_rwgpio(struct aml_value *conn, int b
 }
 
 void
-aml_rwgsb(struct aml_value *conn, int bpos, int blen, struct aml_value *val,
-int mode, int flag)
+aml_rwgsb(struct aml_value *conn, int alen, int bpos, int blen,
+struct aml_value *val, int mode, int flag)
 {
union acpi_resource *crs = (union acpi_resource *)conn->v_buffer;
struct aml_node *node;
@@ -2564,6 +2564,14 @@ aml_rwgsb(struct aml_value *conn, int bp
cmdlen = 1;
buflen = 2;
break;
+   case 0x0b:  /* AttribBytes */
+   cmdlen = 1;
+   buflen = alen;
+   break;
+   case 0x0e:  /* AttribRawBytes */
+   cmdlen = 1;
+   cmdlen = alen;
+   break;
default:
aml_die("unsupported access type 0x%x", flag);
break;
@@ -2709,7 +2717,8 @@ aml_rwfield(struct aml_value *fld, int b
fld->v_field.flags);
break;
case ACPI_OPREG_GSB:
-   aml_rwgsb(ref2, fld->v_field.bitpos + bpos, blen,
+   aml_rwgsb(ref2, fld->v_field.ref3,
+   fld->v_field.bitpos + bpos, blen,
val, mode, fld->v_field.flags);
break;
default:
@@ -2795,17 +2804,17 @@ aml_parsefieldlist(struct aml_scope *msc
bpos = 0;
while (mscope->pos < mscope->end) {
switch (*mscope->pos) {
-   case 0x00: /* reserved, length */
+   case 0x00: /* ReservedField */
mscope->pos++;
blen = aml_parselength(mscope);
break;
-   case 0x01: /* attrib */
+   case 0x01: /* AccessField */
mscope->pos++;
blen = 0;
flags = aml_get8(mscope->pos++);
flags |= aml_get8(mscope->pos++) << 8;
break;
-   case 0x02: /* connection */
+   case 0x02: /* ConnectionField */
mscope->pos++;
blen = 0;
conn = aml_parse(mscope, 'o', "Connection");
@@ -2813,7 +2822,14 @@ aml_parsefieldlist(struct aml_scope *msc
aml_die("Could not parse connection");
conn->node = mscope->node;
break;
-   default: /* 4-byte name, length */
+   case 0x03: /* ExtendedAccessField */
+   mscope->pos++;
+   blen = 0;
+   flags = aml_get8(mscope->pos++);
+   flags |= aml_get8(mscope->pos++) << 8;
+   indexval = aml_get8(mscope->pos++);
+   break;
+   default: /* NamedField */
mscope->pos = aml_parsename(mscope->node, mscope->pos,
&rv, 1);
blen = aml_parselength(mscope);



Re: Fix acpi(4) GeneralSerialBus implementation

2018-05-19 Thread Mark Kettenis
> Date: Fri, 18 May 2018 22:21:06 -0700
> From: Mike Larkin 
> 
> > @@ -2564,6 +2564,14 @@ aml_rwgsb(struct aml_value *conn, int bp
> > cmdlen = 1;
> > buflen = 2;
> > break;
> > +   case 0x0b:  /* AttribBytes */
> > +   cmdlen = 1;
> > +   buflen = alen;
> > +   break;
> > +   case 0x0e:  /* AttribRawBytes */
> > +   cmdlen = 1;
> > +   cmdlen = alen;
> 
> The previous two lines don't look right...

Good catch.  Here is a new diff with that fixed.

ok?


Index: dev/acpi/dsdt.c
===
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.239
diff -u -p -r1.239 dsdt.c
--- dev/acpi/dsdt.c 17 May 2018 20:46:45 -  1.239
+++ dev/acpi/dsdt.c 19 May 2018 07:24:32 -
@@ -2293,7 +2293,7 @@ aml_register_regionspace(struct aml_node
 
 void aml_rwgen(struct aml_value *, int, int, struct aml_value *, int, int);
 void aml_rwgpio(struct aml_value *, int, int, struct aml_value *, int, int);
-void aml_rwgsb(struct aml_value *, int, int, struct aml_value *, int, int);
+void aml_rwgsb(struct aml_value *, int, int, int, struct aml_value *, int, 
int);
 void aml_rwindexfield(struct aml_value *, struct aml_value *val, int);
 void aml_rwfield(struct aml_value *, int, int, struct aml_value *, int);
 
@@ -2520,8 +2520,8 @@ aml_rwgpio(struct aml_value *conn, int b
 #ifndef SMALL_KERNEL
 
 void
-aml_rwgsb(struct aml_value *conn, int bpos, int blen, struct aml_value *val,
-int mode, int flag)
+aml_rwgsb(struct aml_value *conn, int alen, int bpos, int blen,
+struct aml_value *val, int mode, int flag)
 {
union acpi_resource *crs = (union acpi_resource *)conn->v_buffer;
struct aml_node *node;
@@ -2566,6 +2566,14 @@ aml_rwgsb(struct aml_value *conn, int bp
cmdlen = 1;
buflen = 2;
break;
+   case 0x0b:  /* AttribBytes */
+   cmdlen = 1;
+   buflen = alen;
+   break;
+   case 0x0e:  /* AttribRawBytes */
+   cmdlen = 0;
+   buflen = alen;
+   break;
default:
aml_die("unsupported access type 0x%x", flag);
break;
@@ -2714,7 +2722,8 @@ aml_rwfield(struct aml_value *fld, int b
break;
 #ifndef SMALL_KERNEL
case ACPI_OPREG_GSB:
-   aml_rwgsb(ref2, fld->v_field.bitpos + bpos, blen,
+   aml_rwgsb(ref2, fld->v_field.ref3,
+   fld->v_field.bitpos + bpos, blen,
val, mode, fld->v_field.flags);
break;
 #endif
@@ -2801,17 +2810,17 @@ aml_parsefieldlist(struct aml_scope *msc
bpos = 0;
while (mscope->pos < mscope->end) {
switch (*mscope->pos) {
-   case 0x00: /* reserved, length */
+   case 0x00: /* ReservedField */
mscope->pos++;
blen = aml_parselength(mscope);
break;
-   case 0x01: /* attrib */
+   case 0x01: /* AccessField */
mscope->pos++;
blen = 0;
flags = aml_get8(mscope->pos++);
flags |= aml_get8(mscope->pos++) << 8;
break;
-   case 0x02: /* connection */
+   case 0x02: /* ConnectionField */
mscope->pos++;
blen = 0;
conn = aml_parse(mscope, 'o', "Connection");
@@ -2819,7 +2828,14 @@ aml_parsefieldlist(struct aml_scope *msc
aml_die("Could not parse connection");
conn->node = mscope->node;
break;
-   default: /* 4-byte name, length */
+   case 0x03: /* ExtendedAccessField */
+   mscope->pos++;
+   blen = 0;
+   flags = aml_get8(mscope->pos++);
+   flags |= aml_get8(mscope->pos++) << 8;
+   indexval = aml_get8(mscope->pos++);
+   break;
+   default: /* NamedField */
mscope->pos = aml_parsename(mscope->node, mscope->pos,
&rv, 1);
blen = aml_parselength(mscope);



Wake the acpi thread up for gpio events

2018-05-19 Thread Mark Kettenis
Without the wakeup, the event doesn't get scheduled until some other
event wakes up the acpi thread.  On one of my machines the gpio event
reads a status byte over i2c in repsonse of a gpio event.  Without the
wakeup that status byte has often been cleared/overwritten by the time
the event gets scheduled.

ok?


Index: acpi.c
===
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.343
diff -u -p -r1.343 acpi.c
--- acpi.c  17 May 2018 20:46:45 -  1.343
+++ acpi.c  19 May 2018 19:35:59 -
@@ -861,6 +861,7 @@ acpi_gpio_event(void *arg)
struct acpi_gpio_event *ev = arg;
 
acpi_addtask(acpi_softc, acpi_gpio_event_task, ev->node, ev->pin);
+   acpi_wakeup(acpi_softc);
return 1;
 }
 



dwiic acpi improvement

2018-05-19 Thread Mark Kettenis
I'm working on some i2c drivers that are closely tied to acpi.  These
drivers need to call into acpi and need to know their acpi node.  The
diff below makes dwiic(4) pass the acpi node as the cookie to its
children.  This matches what we do in ofw/fdt land where we pass the
device tree node.

ok?


Index: dwiic_acpi.c
===
RCS file: /cvs/src/sys/dev/acpi/dwiic_acpi.c,v
retrieving revision 1.5
diff -u -p -r1.5 dwiic_acpi.c
--- dwiic_acpi.c18 May 2018 06:49:47 -  1.5
+++ dwiic_acpi.c19 May 2018 19:40:43 -
@@ -393,6 +393,7 @@ dwiic_acpi_found_hid(struct aml_node *no
ia.ia_tag = sc->sc_iba.iba_tag;
ia.ia_name = dev;
ia.ia_addr = crs.i2c_addr;
+   ia.ia_cookie = node->parent;
 
config_found(sc->sc_iic, &ia, dwiic_i2c_print);
node->parent->attached = 1;



Re: patch: add --localize-hidden option to objcopy

2018-05-20 Thread Mark Kettenis
> Date: Sun, 20 May 2018 10:26:44 +0200
> From: Sebastien Marie 
> 
> Hi,
> 
> While trying to build git HEAD of radare2, I found us objcopy(1) doesn't
> have the --localize-hidden option.
> 
> As the option was proposed in
> https://sourceware.org/ml/binutils/2006-06/msg00204.html (in 2006), and
> commited in GPLv2 tree of binutils, I think the patch is suitable for us
> too.
> 
> Diff to add the option below.
> 
> Link to the backported commit:
> https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=commitdiff;h=d58c2e3acdba2aadf3a47d741236fa02d7bb04ff;hp=22a84b55803f2adae036b553f7ca347ba02744be
> 
> Thanks.

There is a minor tabs vs. spaces issue in the binutils.texi bit.
Otherwise this is ok kettenis@

> -- 
> Sebastien Marie
> 
> https://sourceware.org/ml/binutils/2006-06/msg00204.html
> from Richard Sandiford
> 
> This patch adds a --localize-hidden option to objcopy.  As its name
> suggests, it converts all global or weak STV_HIDDEN or STV_INTERNAL
> symbols into local symbols.  It is equivalent to listing all such
> symbols using separate -L options.
> 
> Index: objcopy.c
> ===
> RCS file: /cvs/src/gnu/usr.bin/binutils-2.17/binutils/objcopy.c,v
> retrieving revision 1.4
> diff -u -p -r1.4 objcopy.c
> --- objcopy.c 15 Nov 2015 04:13:17 -  1.4
> +++ objcopy.c 20 May 2018 08:06:13 -
> @@ -190,6 +190,9 @@ static bfd_boolean remove_leading_char =
>  /* Whether to permit wildcard in symbol comparison.  */
>  static bfd_boolean wildcard = FALSE;
>  
> +/* True if --localize-hidden is in effect.  */
> +static bfd_boolean localize_hidden = FALSE;
> +
>  /* List of symbols to strip, keep, localize, keep-global, weaken,
> or redefine.  */
>  static struct symlist *strip_specific_list = NULL;
> @@ -240,6 +243,7 @@ enum command_line_switch
>  OPTION_STRIP_UNNEEDED_SYMBOL,
>  OPTION_STRIP_UNNEEDED_SYMBOLS,
>  OPTION_KEEP_SYMBOLS,
> +OPTION_LOCALIZE_HIDDEN,
>  OPTION_LOCALIZE_SYMBOLS,
>  OPTION_GLOBALIZE_SYMBOL,
>  OPTION_GLOBALIZE_SYMBOLS,
> @@ -328,6 +332,7 @@ static struct option copy_options[] =
>{"keep-global-symbols", required_argument, 0, OPTION_KEEPGLOBAL_SYMBOLS},
>{"keep-symbol", required_argument, 0, 'K'},
>{"keep-symbols", required_argument, 0, OPTION_KEEP_SYMBOLS},
> +  {"localize-hidden", no_argument, 0, OPTION_LOCALIZE_HIDDEN},
>{"localize-symbol", required_argument, 0, 'L'},
>{"localize-symbols", required_argument, 0, OPTION_LOCALIZE_SYMBOLS},
>{"no-adjust-warnings", no_argument, 0, OPTION_NO_CHANGE_WARNINGS},
> @@ -428,6 +433,7 @@ copy_usage (FILE *stream, int exit_statu
>   --only-keep-debug Strip everything but the debug 
> information\n\
>-K --keep-symbol   Do not strip symbol \n\
>   --keep-file-symbols   Do not strip file symbol(s)\n\
> + --localize-hidden Turn all ELF hidden symbols into locals\n\
>-L --localize-symbol   Force symbol  to be marked as a 
> local\n\
>   --globalize-symbol  Force symbol  to be marked as a 
> global\n\
>-G --keep-global-symbolLocalize all symbols except \n\
> @@ -809,6 +815,24 @@ is_strip_section (bfd *abfd ATTRIBUTE_UN
>return FALSE;
>  }
>  
> +/* Return true if SYM is a hidden symbol.  */
> +
> +static bfd_boolean
> +is_hidden_symbol (asymbol *sym)
> +{
> +  elf_symbol_type *elf_sym;
> +
> +  elf_sym = elf_symbol_from (sym->the_bfd, sym);
> +  if (elf_sym != NULL)
> +switch (ELF_ST_VISIBILITY (elf_sym->internal_elf_sym.st_other))
> +  {
> +  case STV_HIDDEN:
> +  case STV_INTERNAL:
> +   return TRUE;
> +  }
> +  return FALSE;
> +}
> +
>  /* Choose which symbol entries to copy; put the result in OSYMS.
> We don't copy in place, because that confuses the relocs.
> Return the number of symbols to print.  */
> @@ -955,7 +979,8 @@ filter_symbols (bfd *abfd, bfd *obfd, as
> && (flags & (BSF_GLOBAL | BSF_WEAK))
> && (is_specified_symbol (name, localize_specific_list)
> || (keepglobal_specific_list != NULL
> -   && ! is_specified_symbol (name, 
> keepglobal_specific_list
> +   && ! is_specified_symbol (name, keepglobal_specific_list))
> +   || (localize_hidden && is_hidden_symbol (sym
>   {
> sym->flags &= ~ (BSF_GLOBAL | BSF_WEAK);
> sym->flags |= BSF_LOCAL;
> @@ -1532,6 +1557,7 @@ copy_object (bfd *ibfd, bfd *obfd)
>|| strip_symbols == STRIP_UNNEEDED
>|| strip_symbols == STRIP_NONDEBUG
>|| discard_locals != LOCALS_UNDEF
> +  || localize_hidden
>|| strip_specific_list != NULL
>|| keep_specific_list != NULL
>|| localize_specific_list != NULL
> @@ -3059,6 +3085,10 @@ copy_main (int argc, char *argv[])
>   case OPTION_KEEP_SYMBOLS:
> add_specific_symbols (optarg, &keep_specific_list);
> break;
> +
> + case OPTION_LOCALIZE_H

Re: Wake the acpi thread up for gpio events

2018-05-20 Thread Mark Kettenis
> Date: Sun, 20 May 2018 10:44:49 +0200
> From: Martin Pieuchot 
> 
> On 19/05/18(Sat) 21:39, Mark Kettenis wrote:
> > Without the wakeup, the event doesn't get scheduled until some other
> > event wakes up the acpi thread.  On one of my machines the gpio event
> > reads a status byte over i2c in repsonse of a gpio event.  Without the
> > wakeup that status byte has often been cleared/overwritten by the time
> > the event gets scheduled.
> > 
> > ok?
> 
> ok mpi@
> 
> Then why not make acpi_addtask() call acpi_wakeup() if it could enqueue
> a task?  This is how task_add(9) work.  Most of the code paths already
> use the pattern your suggesting. 

I was thinking the same thing.  It seems acpi_interrupt() schedules a
couple of tasks and does a single wakeup.  There are also some
scheduling sleep-related tasks that don't have an acpi_wakeup()
associated with them.  I don't see a fundamental reason why we can't
do this though.  But maybe I'm missing something?

> > Index: acpi.c
> > ===
> > RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
> > retrieving revision 1.343
> > diff -u -p -r1.343 acpi.c
> > --- acpi.c  17 May 2018 20:46:45 -  1.343
> > +++ acpi.c  19 May 2018 19:35:59 -
> > @@ -861,6 +861,7 @@ acpi_gpio_event(void *arg)
> > struct acpi_gpio_event *ev = arg;
> >  
> > acpi_addtask(acpi_softc, acpi_gpio_event_task, ev->node, ev->pin);
> > +   acpi_wakeup(acpi_softc);
> > return 1;
> >  }
> >  
> > 
> 



Re: dwiic acpi improvement

2018-05-20 Thread Mark Kettenis
> Date: Sat, 19 May 2018 18:48:15 -0700
> From: Mike Larkin 
> 
> On Sat, May 19, 2018 at 09:44:22PM +0200, Mark Kettenis wrote:
> > I'm working on some i2c drivers that are closely tied to acpi.  These
> > drivers need to call into acpi and need to know their acpi node.  The
> > diff below makes dwiic(4) pass the acpi node as the cookie to its
> > children.  This matches what we do in ofw/fdt land where we pass the
> > device tree node.
> > 
> > ok?
> > 
> 
> Sure, ok mlarkin

Turns out I need interrupts as well.

ok?

Index: dwiic_acpi.c
===
RCS file: /cvs/src/sys/dev/acpi/dwiic_acpi.c,v
retrieving revision 1.6
diff -u -p -r1.6 dwiic_acpi.c
--- dwiic_acpi.c20 May 2018 09:30:00 -  1.6
+++ dwiic_acpi.c20 May 2018 18:49:22 -
@@ -395,6 +395,9 @@ dwiic_acpi_found_hid(struct aml_node *no
ia.ia_addr = crs.i2c_addr;
ia.ia_cookie = node->parent;
 
+   if (crs.irq_int != 0 || crs.gpio_int_node != NULL)
+   ia.ia_intr = &crs;
+
config_found(sc->sc_iic, &ia, dwiic_i2c_print);
node->parent->attached = 1;
 



sdhc(4) ACPI improvements

2018-05-20 Thread Mark Kettenis
Diff below does two things:

1. Put controllers and child devices into _PS0.  It seems the BIOS is
   supposed to deliver them to us in that state, but apparently some
   BIOSen don't do that.

2. Override the card detect if ACPI says that the child devices are
   non-removable.  Apparently SDHC card detect is borked (or simply
   not implemented) on the Intel SDIO controllers.

With these diffs, the SDIO WiFi in my Asus X205TA is probed correctly.
And it even works with the bwfm(4) driver after some further magic.

ok?


Index: dev/acpi/sdhc_acpi.c
===
RCS file: /cvs/src/sys/dev/acpi/sdhc_acpi.c,v
retrieving revision 1.9
diff -u -p -r1.9 sdhc_acpi.c
--- dev/acpi/sdhc_acpi.c25 Oct 2016 06:48:58 -  1.9
+++ dev/acpi/sdhc_acpi.c20 May 2018 23:14:26 -
@@ -70,8 +70,11 @@ const char *sdhc_hids[] = {
 };
 
 intsdhc_acpi_parse_resources(int, union acpi_resource *, void *);
-intsdhc_acpi_card_detect(struct sdhc_softc *);
+intsdhc_acpi_card_detect_nonremovable(struct sdhc_softc *);
+intsdhc_acpi_card_detect_gpio(struct sdhc_softc *);
 intsdhc_acpi_card_detect_intr(void *);
+void   sdhc_acpi_power_on(struct sdhc_acpi_softc *, struct aml_node *);
+void   sdhc_acpi_explore(struct sdhc_acpi_softc *);
 
 int
 sdhc_acpi_match(struct device *parent, void *match, void *aux)
@@ -122,10 +125,12 @@ sdhc_acpi_attach(struct device *parent, 
}
 
if (sc->sc_gpio_io_node && sc->sc_gpio_io_node->gpio) {
-   sc->sc.sc_card_detect = sdhc_acpi_card_detect;
+   sc->sc.sc_card_detect = sdhc_acpi_card_detect_gpio;
printf(", gpio");
}
 
+   printf("\n");
+
if (sc->sc_gpio_int_node && sc->sc_gpio_int_node->gpio) {
struct acpi_gpio *gpio = sc->sc_gpio_int_node->gpio;
 
@@ -133,7 +138,8 @@ sdhc_acpi_attach(struct device *parent, 
sc->sc_gpio_int_flags, sdhc_acpi_card_detect_intr, sc);
}
 
-   printf("\n");
+   sdhc_acpi_power_on(sc, sc->sc_node);
+   sdhc_acpi_explore(sc);
 
sc->sc.sc_host = &sc->sc_host;
sc->sc.sc_dmat = &pci_bus_dma_tag;
@@ -175,7 +181,13 @@ sdhc_acpi_parse_resources(int crsidx, un
 }
 
 int
-sdhc_acpi_card_detect(struct sdhc_softc *ssc)
+sdhc_acpi_card_detect_nonremovable(struct sdhc_softc *ssc)
+{
+   return 1;
+}
+
+int
+sdhc_acpi_card_detect_gpio(struct sdhc_softc *ssc)
 {
struct sdhc_acpi_softc *sc = (struct sdhc_acpi_softc *)ssc;
struct acpi_gpio *gpio = sc->sc_gpio_io_node->gpio;
@@ -193,4 +205,48 @@ sdhc_acpi_card_detect_intr(void *arg)
sdhc_needs_discover(&sc->sc);
 
return (1);
+}
+
+void
+sdhc_acpi_power_on(struct sdhc_acpi_softc *sc, struct aml_node *node)
+{
+   node = aml_searchname(node, "_PS0");
+   if (node && aml_evalnode(sc->sc_acpi, node, 0, NULL, NULL))
+   printf("%s: _PS0 failed\n", sc->sc.sc_dev.dv_xname);
+}
+
+int
+sdhc_acpi_do_explore(struct aml_node *node, void *arg)
+{
+   struct sdhc_acpi_softc *sc = arg;
+   int64_t sta, rmv;
+
+   /* We're only interested in our children. */
+   if (node == sc->sc_node)
+   return 0;
+
+   /* Only consider devices that are actually present. */
+   if (node->value == NULL ||
+   node->value->type != AML_OBJTYPE_DEVICE)
+   return 1;
+   if (aml_evalinteger(sc->sc_acpi, node, "_STA", 0, NULL, &sta))
+   sta = STA_PRESENT | STA_ENABLED | STA_DEV_OK | 0x1000;
+   if ((sta & STA_PRESENT) == 0)
+   return 1;
+
+   /* Override card detect if we have non-removable devices. */
+   if (aml_evalinteger(sc->sc_acpi, node, "_RMV", 0, NULL, &rmv))
+   rmv = 1;
+   if (rmv == 0 && sc->sc.sc_card_detect == NULL)
+   sc->sc.sc_card_detect = sdhc_acpi_card_detect_nonremovable;
+
+   sdhc_acpi_power_on(sc, node);
+
+   return 1;
+}
+
+void
+sdhc_acpi_explore(struct sdhc_acpi_softc *sc)
+{
+   aml_walknodes(sc->sc_node, AML_WALK_PRE, sdhc_acpi_do_explore, sc);
 }



dwiic(4) fix

2018-05-21 Thread Mark Kettenis
The diff below fixes I2C_OP_WRITE_WITH_STOP operations.  Currently we
run the read completion code for those operations, but since there is
no data to read, this fails.  Instead, this waits until a stop is
detected.  That doesn't seem to work for I2C_F_POLL operations though,
so in that case we wait until the bus is idle.  This also adds
interlocks (using splbio/splx) on the existing tsleep() operations.

This doesn't fix all the issues with the driver.  In particular it
seems that large reads still cause problems.  I think a somewhat more
invasive re-write of the dwiic_i2c_exec() function is needed.  But I'd
like to get this in before I embark on that.

ok?


Index: dev/ic/dwiic.c
===
RCS file: /cvs/src/sys/dev/ic/dwiic.c,v
retrieving revision 1.3
diff -u -p -r1.3 dwiic.c
--- dev/ic/dwiic.c  19 Jan 2018 18:20:38 -  1.3
+++ dev/ic/dwiic.c  21 May 2018 10:37:50 -
@@ -192,6 +192,7 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
u_int32_t ic_con, st, cmd, resp;
int retries, tx_limit, rx_avail, x, readpos;
uint8_t *b;
+   int s;
 
if (sc->sc_busy)
return 1;
@@ -245,12 +246,14 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
if (flags & I2C_F_POLL)
DELAY(200);
else {
+   s = splbio();
dwiic_read(sc, DW_IC_CLR_INTR);
dwiic_write(sc, DW_IC_INTR_MASK, DW_IC_INTR_TX_EMPTY);
 
if (tsleep(&sc->sc_writewait, PRIBIO, "dwiic", hz / 2) != 0)
printf("%s: timed out waiting for tx_empty intr\n",
sc->sc_dev.dv_xname);
+   splx(s);
}
 
/* send our command, one byte at a time */
@@ -320,7 +323,7 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
 * As TXFLR fills up, we need to clear it out by reading all
 * available data.
 */
-   while (tx_limit == 0 || x == len) {
+   while (I2C_OP_READ_P(op) && (tx_limit == 0 || x == len)) {
DPRINTF(("%s: %s: tx_limit %d, sent %d read reqs\n",
sc->sc_dev.dv_xname, __func__, tx_limit, x));
 
@@ -332,6 +335,7 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
DELAY(50);
}
} else {
+   s = splbio();
dwiic_read(sc, DW_IC_CLR_INTR);
dwiic_write(sc, DW_IC_INTR_MASK,
DW_IC_INTR_RX_FULL);
@@ -341,6 +345,7 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
printf("%s: timed out waiting for "
"rx_full intr\n",
sc->sc_dev.dv_xname);
+   splx(s);
 
rx_avail = dwiic_read(sc, DW_IC_RXFLR);
}
@@ -378,6 +383,32 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
}
}
 
+   if (I2C_OP_STOP_P(op) && I2C_OP_WRITE_P(op)) {
+   if (flags & I2C_F_POLL) {
+   /* wait for bus to be idle */
+   for (retries = 100; retries > 0; retries--) {
+   st = dwiic_read(sc, DW_IC_STATUS);
+   if (!(st & DW_IC_STATUS_ACTIVITY))
+   break;
+   DELAY(1000);
+   }
+   if (st & DW_IC_STATUS_ACTIVITY)
+   printf("%s: timed out waiting for bus idle\n",
+   sc->sc_dev.dv_xname);
+   } else {
+   s = splbio();
+   while (sc->sc_busy) {
+   dwiic_write(sc, DW_IC_INTR_MASK,
+   DW_IC_INTR_STOP_DET);
+   if (tsleep(&sc->sc_busy, PRIBIO, "dwiic",
+   hz / 2) != 0)
+   printf("%s: timed out waiting for "
+   "stop intr\n",
+   sc->sc_dev.dv_xname);
+   }
+   splx(s);
+   }
+   }
sc->sc_busy = 0;
 
return 0;
@@ -449,6 +480,11 @@ dwiic_intr(void *arg)
DPRINTF(("%s: %s: waking up writer\n",
sc->sc_dev.dv_xname, __func__));
wakeup(&sc->sc_writewait);
+   }
+   if (stat & DW_IC_INTR_STOP_DET) {
+   dwiic_write(sc, DW_IC_INTR_MASK, 0);
+   sc->sc_busy = 0;
+   wakeup(&sc->sc_busy);
}
}
 



cosmetic sdio diff

2018-05-21 Thread Mark Kettenis
This diff improves the way we printf "not configured" sdio devices.

Before:

(manufacturer 0x2d0, product 0x4334)at sdmmc1 function 2 not configured

After:

manufacturer 0x02d0, product 0x4334 at sdmmc1 function 2 not configured

This is somewhat similar to how we print "unknown" pci devices,
although I left out printing "unknown" here since we don't have a
table wit known vendors/products.

ok?


Index: dev/sdmmc/sdmmc_io.c
===
RCS file: /cvs/src/sys/dev/sdmmc/sdmmc_io.c,v
retrieving revision 1.32
diff -u -p -r1.32 sdmmc_io.c
--- dev/sdmmc/sdmmc_io.c11 Feb 2018 20:58:40 -  1.32
+++ dev/sdmmc/sdmmc_io.c21 May 2018 11:31:31 -
@@ -305,19 +305,18 @@ sdmmc_print(void *aux, const char *pnp)
if (i != 0)
printf("\"");
 
-   if (cis->manufacturer != SDMMC_VENDOR_INVALID &&
+   if (cis->manufacturer != SDMMC_VENDOR_INVALID ||
cis->product != SDMMC_PRODUCT_INVALID) {
-   printf("%s(", i ? " " : "");
+   printf("%s", i ? " " : "");
if (cis->manufacturer != SDMMC_VENDOR_INVALID)
-   printf("manufacturer 0x%x%s",
+   printf("manufacturer 0x%04x%s",
cis->manufacturer,
cis->product == SDMMC_PRODUCT_INVALID ?
"" : ", ");
if (cis->product != SDMMC_PRODUCT_INVALID)
-   printf("product 0x%x", cis->product);
-   printf(")");
+   printf("product 0x%04x", cis->product);
}
-   printf("%sat %s", i ? " " : "", pnp);
+   printf(" at %s", pnp);
}
printf(" function %d", sf->number);
 



INT33F4 device information needed

2018-05-21 Thread Mark Kettenis
Hi Folks,

For a driver that I'm working on I need a variety of acpidump output
to get a better understanding of how the hardware behaves.  If you
have a machine that has the following line in its dmesg:

  "INT33F4" at iic0 addr 0x34 not configured

please send me:

1. A tar file with all the files in /var/db/acpi.

2. A full dmesg.

This device is typically found on cheap Intel Atom laptops/tablets/2-in-1s.

Thanks,

Mark



Re: unbreak gsckbc (possibly iockbc and mkbc)

2018-05-22 Thread Mark Kettenis
> Date: Tue, 22 May 2018 12:29:21 +0200
> From: Otto Moerbeek 
> 
> On Thu, May 03, 2018 at 05:23:18PM +, Miod Vallat wrote:
> 
> > sys/dev/pckbc/pckbd.c introduces a buglet, where the value computed for
> > local variable `table' in pckbd_set_xtscancode() in the non-translating
> > case, is overwritten by accident.
> > 
> > Unfortunately, this means that the keyboard ends up using a scancode set
> > which is not the one expected by the driver, and hilarity ensues, such
> > as key up events not translated correctly, and neither ctrl or caps
> > lock.
> > 
> > Unfortunately this breaks at least gsckbc(4/hppa), which is a controller
> > where you can't plug a DIN keyboard so a "modern" PS/2 keyboard is
> > required, and that logic can be shunt.
> > 
> > This is very inconvenient, as most of the hppa machines where the X
> > server works are gsckbc machines, and 6.3 can't be installed on them
> > because of this bug (but then, noone seems to have noticed, so this is
> > hardly relevant).
> > 
> > Simple fix below.
> 
> A report this fixes the problme indeed came by on misc@
> 
> Imo this should be committed.

Did anyone at least try it on non-miod hardware (i.e. amd64)?

I guess we'll find out if we commit this diff...

ok kettenis@

> > Index: pckbd.c
> > ===
> > RCS file: /OpenBSD/src/sys/dev/pckbc/pckbd.c,v
> > retrieving revision 1.44
> > diff -u -p -r1.44 pckbd.c
> > --- pckbd.c 6 Jan 2018 18:51:20 -   1.44
> > +++ pckbd.c 2 May 2018 18:58:28 -
> > @@ -214,7 +214,7 @@ int
> >  pckbd_set_xtscancode(pckbc_tag_t kbctag, pckbc_slot_t kbcslot,
> >  struct pckbd_internal *id)
> >  {
> > -   int table;
> > +   int table = 3;
> >  
> > if (pckbc_xt_translation(kbctag)) {
> >  #ifdef DEBUG
> > @@ -247,7 +247,7 @@ pckbd_set_xtscancode(pckbc_tag_t kbctag,
> > }
> >  
> > /* keep falling back until we hit a table that looks usable. */
> > -   for (table = 3; table >= 1; table--) {
> > +   for (; table >= 1; table--) {
> > u_char cmd[2];
> >  #ifdef DEBUG
> > printf("pckbd: trying table %d\n", table);
> 
> 



Re: dwiic(4) fix

2018-05-22 Thread Mark Kettenis
> Date: Mon, 21 May 2018 17:25:47 -0700
> From: Mike Larkin 
> 
> On Mon, May 21, 2018 at 12:44:47PM +0200, Mark Kettenis wrote:
> > The diff below fixes I2C_OP_WRITE_WITH_STOP operations.  Currently we
> > run the read completion code for those operations, but since there is
> > no data to read, this fails.  Instead, this waits until a stop is
> > detected.  That doesn't seem to work for I2C_F_POLL operations though,
> > so in that case we wait until the bus is idle.  This also adds
> > interlocks (using splbio/splx) on the existing tsleep() operations.
> > 
> > This doesn't fix all the issues with the driver.  In particular it
> > seems that large reads still cause problems.  I think a somewhat more
> > invasive re-write of the dwiic_i2c_exec() function is needed.  But I'd
> > like to get this in before I embark on that.
> > 
> > ok?
> > 
> 
> The diff reads ok to me, do you want us to do any sort of testing here before
> commit?

Testing is always appreciated, and a goood idea if you own a machine
that relies on dwiic(4).  For example those with machines that have a
keyboard or touchpad/screen connected over i2c.

Cheers,

Mark

> > Index: dev/ic/dwiic.c
> > ===
> > RCS file: /cvs/src/sys/dev/ic/dwiic.c,v
> > retrieving revision 1.3
> > diff -u -p -r1.3 dwiic.c
> > --- dev/ic/dwiic.c  19 Jan 2018 18:20:38 -  1.3
> > +++ dev/ic/dwiic.c  21 May 2018 10:37:50 -
> > @@ -192,6 +192,7 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
> > u_int32_t ic_con, st, cmd, resp;
> > int retries, tx_limit, rx_avail, x, readpos;
> > uint8_t *b;
> > +   int s;
> >  
> > if (sc->sc_busy)
> > return 1;
> > @@ -245,12 +246,14 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
> > if (flags & I2C_F_POLL)
> > DELAY(200);
> > else {
> > +   s = splbio();
> > dwiic_read(sc, DW_IC_CLR_INTR);
> > dwiic_write(sc, DW_IC_INTR_MASK, DW_IC_INTR_TX_EMPTY);
> >  
> > if (tsleep(&sc->sc_writewait, PRIBIO, "dwiic", hz / 2) != 0)
> > printf("%s: timed out waiting for tx_empty intr\n",
> > sc->sc_dev.dv_xname);
> > +   splx(s);
> > }
> >  
> > /* send our command, one byte at a time */
> > @@ -320,7 +323,7 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
> >  * As TXFLR fills up, we need to clear it out by reading all
> >  * available data.
> >  */
> > -   while (tx_limit == 0 || x == len) {
> > +   while (I2C_OP_READ_P(op) && (tx_limit == 0 || x == len)) {
> > DPRINTF(("%s: %s: tx_limit %d, sent %d read reqs\n",
> > sc->sc_dev.dv_xname, __func__, tx_limit, x));
> >  
> > @@ -332,6 +335,7 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
> > DELAY(50);
> > }
> > } else {
> > +   s = splbio();
> > dwiic_read(sc, DW_IC_CLR_INTR);
> > dwiic_write(sc, DW_IC_INTR_MASK,
> > DW_IC_INTR_RX_FULL);
> > @@ -341,6 +345,7 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
> > printf("%s: timed out waiting for "
> > "rx_full intr\n",
> > sc->sc_dev.dv_xname);
> > +   splx(s);
> >  
> > rx_avail = dwiic_read(sc, DW_IC_RXFLR);
> > }
> > @@ -378,6 +383,32 @@ dwiic_i2c_exec(void *cookie, i2c_op_t op
> > }
> > }
> >  
> > +   if (I2C_OP_STOP_P(op) && I2C_OP_WRITE_P(op)) {
> > +   if (flags & I2C_F_POLL) {
> > +   /* wait for bus to be idle */
> > +   for (retries = 100; retries > 0; retries--) {
> > +   st = dwiic_read(sc, DW_IC_STATUS);
> > +   if (!(st & DW_IC_STATUS_ACTIVITY))
> > +   break;
> > +   DELAY(1000);
> > +   }
> > +   if (st & DW_IC_STATUS_ACTIVITY)
> > +   printf("%s: timed out waiting for bus idle\n",
> > +  

Re: SMCCC 1.1 support for psci(4)

2018-05-22 Thread Mark Kettenis
> Date: Fri, 4 May 2018 20:14:38 +0200 (CEST)
> From: Mark Kettenis 
> 
> > Date: Tue, 1 May 2018 11:55:00 +0200 (CEST)
> > From: Mark Kettenis 
> > 
> > So after adding a quick hack to mitigate Spectre variant 2 to ARM
> > Trusted Firmware (ATF), ARM actually designed a proper solution that
> > minimizes the performance loss and makes the presence of the
> > workaround detectable.  This is all documented in an update of the SMC
> > Calling Convention (SMCCC) standard.
> > 
> > The diff below implements support for this solution while keeping
> > support for the hack.  While ARM strongly suggests vendors to update
> > to a version of ATF that implements SMCCC 1.1 the current ATF for the
> > Marvell ARMADA 8040 hasn't been updated yet (but does include the
> > initial hack).
> 
> So it turns out that while I wasn't paying attention, the Marvell
> folks backported SMCCC 1.1 support to their ATF fork.  This means we
> can drop support for the PSCI_VERSION hack without leaving
> MACCHIATOBin owener out in the cold.  I think the code simplification
> is worth it.  It also means we can tell whether a machine is safe or
> not from a dmesg.
> 
> ok?

And in light of Spectre variant 4, I think there is even less reason
to continue support for firmware that doesn't implement SMCCC 1.1.

I'd like to commit this diff such that I can improve the way we signal
that mitigations are present in the firmware.

ok?

> Index: dev/fdt/psci.c
> ===
> RCS file: /cvs/src/sys/dev/fdt/psci.c,v
> retrieving revision 1.7
> diff -u -p -r1.7 psci.c
> --- dev/fdt/psci.c3 May 2018 09:45:57 -   1.7
> +++ dev/fdt/psci.c4 May 2018 18:01:04 -
> @@ -54,7 +54,6 @@ struct psci_softc {
>   uint32_t sc_system_reset;
>   uint32_t sc_cpu_on;
>  
> - uint32_t sc_version;
>   uint32_t sc_smccc_version;
>  };
>  
> @@ -98,6 +97,7 @@ psci_attach(struct device *parent, struc
>   struct psci_softc *sc = (struct psci_softc *)self;
>   struct fdt_attach_args *faa = aux;
>   char method[128];
> + uint32_t version;
>  
>   if (OF_getprop(faa->fa_node, "method", method, sizeof(method))) {
>   if (strcmp(method, "hvc") == 0)
> @@ -127,10 +127,10 @@ psci_attach(struct device *parent, struc
>  
>   psci_sc = sc;
>  
> - sc->sc_version = psci_version();
> - printf(": PSCI %d.%d", sc->sc_version >> 16, sc->sc_version & 0x);
> + version = psci_version();
> + printf(": PSCI %d.%d", version >> 16, version & 0x);
>  
> - if (sc->sc_version >= 0x1) {
> + if (version >= 0x1) {
>   if (psci_features(SMCCC_VERSION) == PSCI_SUCCESS) {
>   sc->sc_smccc_version = smccc_version();
>   printf(", SMCCC %d.%d", sc->sc_smccc_version >> 16,
> @@ -165,11 +165,9 @@ psci_powerdown(void)
>  }
>  
>  /*
> - * Firmware-based workaround for CVE-2017-5715.  We pick the
> - * appropriate mechanism based on the PSCI and SMCCC versions.  We
> - * determine whether the workaround is actually needed the first time
> - * we are invoked such that we only make the firmware call if we
> - * really need to.
> + * Firmware-based workaround for CVE-2017-5715.  We determine whether
> + * the workaround is actually implemented and needed the first time we
> + * are invoked such that we only make the firmware call when appropriate.
>   */
>  
>  void
> @@ -178,14 +176,6 @@ psci_flush_bp_none(void)
>  }
>  
>  void
> -psci_flush_bp_psci_version(void)
> -{
> - struct psci_softc *sc = psci_sc;
> -
> - (*sc->sc_callfn)(PSCI_VERSION, 0, 0, 0);
> -}
> -
> -void
>  psci_flush_bp_smccc_arch_workaround_1(void)
>  {
>   struct psci_softc *sc = psci_sc;
> @@ -199,32 +189,17 @@ psci_flush_bp(void)
>   struct psci_softc *sc = psci_sc;
>   struct cpu_info *ci = curcpu();
>  
> - /* No PSCI or an old version of PSCI; nothing we can do. */
> - if (sc == NULL || sc->sc_version < 0x1) {
> - ci->ci_flush_bp = psci_flush_bp_none;
> - return;
> - }
> -
> - /*
> -  * PSCI 1.0 or later with SMCCC 1.0; invoke PSCI_VERSION and
> -  * hope for the best.
> -  */
> - if (sc->sc_smccc_version < 0x10001) {
> - ci->ci_flush_bp = psci_flush_bp_psci_version;
> - ci->ci_flush_bp();
> - return;
> - }
> -
>   /*
> -  * SMCCC

Re: Automatic configuration of /etc/ttys in installer

2018-05-26 Thread Mark Kettenis
> Date: Tue, 8 May 2018 08:51:14 +0200 (CEST)
> From: Mark Kettenis 
> 
> After my recent changes to armv7 and arm64 the installer and
> single-user mode are usable with a non-standard serial console speed.
> However, the installer will still install an /etc/ttys file with
> std.115200 in it.  This means that getty(8) will change the speed
> which means you get garbage or nothing on your serial connections.
> 
> Here is an attempt to make the installer modify the console entry in
> /etc/ttys to reflect the correct speed.  This uses some of the same
> code that we use to offer i386/amd64 users to switch the console to
> serial.  But it doesn't ask the question since we don't have to guess
> what the console will be.  I restricted the patching to the set of
> speeds that we actually support.
> 
> Is there a better way to do this?

Ping?

> Index: distrib/arm64/ramdisk/install.md
> ===
> RCS file: /cvs/src/distrib/arm64/ramdisk/install.md,v
> retrieving revision 1.9
> diff -u -p -r1.9 install.md
> --- distrib/arm64/ramdisk/install.md  23 Mar 2018 05:02:27 -  1.9
> +++ distrib/arm64/ramdisk/install.md  8 May 2018 06:40:44 -
> @@ -150,4 +150,12 @@ md_congrats() {
>  }
>  
>  md_consoleinfo() {
> + CTTY=console
> + DEFCONS=y
> + case $CSPEED in
> + 9600|19200|38400|57600|115200|150)
> + ;;
> + *)
> + CSPEED=115200;;
> + esac
>  }
> Index: distrib/miniroot/install.sub
> ===
> RCS file: /cvs/src/distrib/miniroot/install.sub,v
> retrieving revision 1.1067
> diff -u -p -r1.1067 install.sub
> --- distrib/miniroot/install.sub  7 May 2018 10:44:01 -   1.1067
> +++ distrib/miniroot/install.sub  8 May 2018 06:40:44 -
> @@ -2637,6 +2637,7 @@ apply() {
>   if [[ $DEFCONS == y ]]; then
>   cp /mnt/etc/ttys /tmp/i/ttys
>   sed -e "/^$CTTY/s/std.9600/std.${CSPEED}/" \
> + -e "/^$CTTY/s/std.115200/std.${CSPEED}/" \
>   -e "/^$CTTY/s/unknown/vt220 /" \
>   -e "/$CTTY/s/off.*/on secure/" /tmp/i/ttys 
> >/mnt/etc/ttys
>   [[ -n $CPROM ]] &&
> 
> 



sximmc(4) SDIO support

2018-05-27 Thread Mark Kettenis
Diff below makes sximmc(4) play nice with our SDIO code.  The
Cubieboard4 (Allwinner A80) isn't entirely happy with this in
combination with bwfm(4).  But as long as you don't bring the
interface that doesn't cause any problems.  There is a power
sequencing glitch that prevents bwfm(4) from attaching anyway.

It seems to work fine on the Banana Pi M2 Berry (Allwinner R40).

The changes are:

- Add SDIO interrupt handling.

- Set a bit to let the CPU access the FIFO.  We inherited this bit
  from U-Boot on the SD/MMC controllers that it brings up, but U-Boot
  doesn't touch the SDIO controllers.

- Fix PIO transfers that are not a multiple of 4 bytes.

- Handle vqmmc-supply.

ok?


Index: dev/fdt/sximmc.c
===
RCS file: /cvs/src/sys/dev/fdt/sximmc.c,v
retrieving revision 1.3
diff -u -p -r1.3 sximmc.c
--- dev/fdt/sximmc.c13 Aug 2017 00:13:07 -  1.3
+++ dev/fdt/sximmc.c27 May 2018 15:00:06 -
@@ -219,6 +219,8 @@ int sximmc_bus_power(sdmmc_chipset_handl
 intsximmc_bus_clock(sdmmc_chipset_handle_t, int, int);
 intsximmc_bus_width(sdmmc_chipset_handle_t, int);
 void   sximmc_exec_command(sdmmc_chipset_handle_t, struct sdmmc_command *);
+void   sximmc_card_intr_mask(sdmmc_chipset_handle_t, int);
+void   sximmc_card_intr_ack(sdmmc_chipset_handle_t);
 
 void   sximmc_pwrseq_pre(uint32_t);
 void   sximmc_pwrseq_post(uint32_t);
@@ -232,6 +234,8 @@ struct sdmmc_chip_functions sximmc_chip_
.bus_clock = sximmc_bus_clock,
.bus_width = sximmc_bus_width,
.exec_command = sximmc_exec_command,
+   .card_intr_mask = sximmc_card_intr_mask,
+   .card_intr_ack = sximmc_card_intr_ack,
 };
 
 struct sximmc_softc {
@@ -265,6 +269,7 @@ struct sximmc_softc {
 
uint32_t sc_gpio[4];
uint32_t sc_vmmc;
+   uint32_t sc_vqmmc;
uint32_t sc_pwrseq;
uint32_t sc_vdd;
 };
@@ -407,6 +412,7 @@ sximmc_attach(struct device *parent, str
gpio_controller_config_pin(sc->sc_gpio, GPIO_CONFIG_INPUT);
 
sc->sc_vmmc = OF_getpropint(sc->sc_node, "vmmc-supply", 0);
+   sc->sc_vqmmc = OF_getpropint(sc->sc_node, "vqmmc-supply", 0);
sc->sc_pwrseq = OF_getpropint(sc->sc_node, "mmc-pwrseq", 0);
 
sc->sc_ih = arm_intr_establish_fdt(faa->fa_node, IPL_BIO,
@@ -489,11 +495,46 @@ sximmc_intr(void *priv)
if (rint) {
sc->sc_intr_rint |= rint;
wakeup(&sc->sc_intr_rint);
+
+   if (rint & SXIMMC_INT_SDIO_INT) {
+   uint32_t imask;
+
+   imask = MMC_READ(sc, SXIMMC_IMASK);
+   imask &= ~SXIMMC_INT_SDIO_INT;
+   MMC_WRITE(sc, SXIMMC_IMASK, imask);
+   sdmmc_card_intr(sc->sc_sdmmc_dev);
+   }
}
 
return 1;
 }
 
+void
+sximmc_card_intr_mask(sdmmc_chipset_handle_t sch, int enable)
+{
+   struct sximmc_softc *sc = sch;
+   uint32_t imask;
+
+   imask = MMC_READ(sc, SXIMMC_IMASK);
+   if (enable)
+   imask |= SXIMMC_INT_SDIO_INT;
+   else
+   imask &= ~SXIMMC_INT_SDIO_INT;
+   MMC_WRITE(sc, SXIMMC_IMASK, imask);
+}
+
+void
+sximmc_card_intr_ack(sdmmc_chipset_handle_t sch)
+{
+   struct sximmc_softc *sc = sch;
+   uint32_t imask;
+
+   MMC_WRITE(sc, SXIMMC_RINT, SXIMMC_INT_SDIO_INT);
+   imask = MMC_READ(sc, SXIMMC_IMASK);
+   imask |= SXIMMC_INT_SDIO_INT;
+   MMC_WRITE(sc, SXIMMC_IMASK, imask);
+}
+
 int
 sximmc_wait_rint(struct sximmc_softc *sc, uint32_t mask, int timeout)
 {
@@ -562,6 +603,10 @@ sximmc_host_reset(sdmmc_chipset_handle_t
printf("%s: host reset succeeded\n", sc->sc_dev.dv_xname);
 #endif
 
+   /* Allow access to the FIFO by the CPU. */
+   MMC_WRITE(sc, SXIMMC_GCTRL,
+   MMC_READ(sc, SXIMMC_GCTRL) | SXIMMC_GCTRL_ACCESS_BY_AHB);
+
MMC_WRITE(sc, SXIMMC_TIMEOUT, 0x);
 
MMC_WRITE(sc, SXIMMC_IMASK,
@@ -625,6 +670,11 @@ sximmc_bus_power(sdmmc_chipset_handle_t 
if (sc->sc_vmmc && vdd > 0)
regulator_enable(sc->sc_vmmc);
 
+   if (sc->sc_vqmmc && vdd > 0)
+   regulator_enable(sc->sc_vqmmc);
+
+   delay(1);
+
if (sc->sc_vdd == 0 && vdd > 0)
sximmc_pwrseq_post(sc->sc_pwrseq);
 
@@ -655,7 +705,7 @@ sximmc_update_clock(struct sximmc_softc 
 
if (retry == 0) {
printf("%s: timeout updating clock\n", sc->sc_dev.dv_xname);
-#ifdef SXIMMC_DEBUG
+#ifndef SXIMMC_DEBUG
printf("GCTRL: 0x%08x\n", MMC_READ(sc, SXIMMC_GCTRL));
printf("CLKCR: 0x%08x\n", MMC_READ(sc, SXIMMC_CLKCR));
printf("TIMEOUT: 0x%08x\n", MMC_READ(sc, SXIMMC_TIMEOUT));
@@ -749,17 +799,34 @@ sximmc_pio_wait(struct sximmc_softc *sc,
 int
 sximmc_pio_transfer(struct sximmc_softc *sc, struct sdmmc_command *cmd)
 {
-   uint32_t *datap = (uint32_t *)cmd->c_data;
-   int i;
+   u_c

local-mac-address

2018-05-27 Thread Mark Kettenis
Looks like u-boot was finally fixed and now assigns a
local-mac-address property to device nodes even if u-boot itself isn't
configured with a network driver.  This is helpful since this means we
can have a static MAC address even if y-boot doesn't touch the
hardware.

Diff below adds the necessary code to dwge(4) to take advantage of this.

ok?


Index: dev/fdt/if_dwxe.c
===
RCS file: /cvs/src/sys/dev/fdt/if_dwxe.c,v
retrieving revision 1.8
diff -u -p -r1.8 if_dwxe.c
--- dev/fdt/if_dwxe.c   27 May 2018 16:19:25 -  1.8
+++ dev/fdt/if_dwxe.c   27 May 2018 19:09:04 -
@@ -411,7 +411,9 @@ dwxe_attach(struct device *parent, struc
else
sc->sc_clk = DWXE_MDIO_CMD_MDC_DIV_RATIO_M_16;
 
-   dwxe_lladdr_read(sc, sc->sc_lladdr);
+   if (OF_getprop(faa->fa_node, "local-mac-address",
+   &sc->sc_lladdr, ETHER_ADDR_LEN) != ETHER_ADDR_LEN)
+   dwxe_lladdr_read(sc, sc->sc_lladdr);
printf(": address %s\n", ether_sprintf(sc->sc_lladdr));
 
/* Do hardware specific initializations. */



Some arm64 cleanup

2018-05-28 Thread Mark Kettenis
machine_reg.h is completely unused
swi.h is referenced from libc's SYS.h but nothing from that file is used
bootconfig.h has some junk that isn't really used

The MAX_BOOT_STRING define in bootconfig.h doesn't really serve a
purpose anymore.  Simply use a fixed-size buffer and strlcpy the
results into it using sizeof.

ok?

Index: sys/arch/arm64/include/bootconfig.h
===
RCS file: /cvs/src/sys/arch/arm64/include/bootconfig.h,v
retrieving revision 1.2
diff -u -p -r1.2 bootconfig.h
--- sys/arch/arm64/include/bootconfig.h 18 Dec 2016 14:40:25 -  1.2
+++ sys/arch/arm64/include/bootconfig.h 28 May 2018 09:03:07 -
@@ -32,9 +32,6 @@
 #ifndef _MACHINE_BOOTCONFIG_H_
 #define_MACHINE_BOOTCONFIG_H_
 
-#defineMAX_BOOT_STRING 255
-extern char bootstring[MAX_BOOT_STRING];
-
 struct arm64_bootparams {
vaddr_t modulep;
vaddr_t kern_l1pt;  /* L1 page table for the kernel */
@@ -45,14 +42,8 @@ struct arm64_bootparams {
void*arg2; // passed to kernel in R2
 };
 
-extern paddr_t physmap[];
-extern u_int physmap_idx;
-
-
 void initarm(struct arm64_bootparams *);
 
 extern char *boot_file;
 
 #endif /* _MACHINE_BOOTCONFIG_H_ */
-
-/* End of bootconfig.h */
Index: sys/arch/arm64/include/machine_reg.h
===
RCS file: sys/arch/arm64/include/machine_reg.h
diff -N sys/arch/arm64/include/machine_reg.h
--- sys/arch/arm64/include/machine_reg.h30 Apr 2017 13:04:49 -  
1.2
+++ /dev/null   1 Jan 1970 00:00:00 -
@@ -1,57 +0,0 @@
-/* $OpenBSD: machine_reg.h,v 1.2 2017/04/30 13:04:49 mpi Exp $ */
-
-/*
- * Copyright (c) 2002, 2003  Genetec Corporation.  All rights reserved.
- * Written by Hiroyuki Bessho for Genetec Corporation.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *notice, this list of conditions and the following disclaimer in the
- *documentation and/or other materials provided with the distribution.
- * 3. The name of Genetec Corporation may not be used to endorse or
- *promote products derived from this software without specific prior
- *written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef _MACHINE_REG_H
-#define _MACHINE_REG_H
-
-/*
- * Logical mapping for onboard/integrated peripherals
- */
-#defineMACHINE_IO_AREA_VBASE   0xfd00
-#define MACHINE_GPIO_VBASE 0xfd00
-#define MACHINE_CLKMAN_VBASE   0xfd10
-#define MACHINE_INTCTL_VBASE   0xfd20
-#define MACHINE_AGPIO_VBASE0xfd30
-#define MACHINE_VBASE_FREE 0xfd40
-/* FFUART and/or BTUART are mapped to this area when
-   used for console */
-
-#define ioreg_read(a)  (*(volatile unsigned *)(a))
-#define ioreg_write(a,v)  (*(volatile unsigned *)(a)=(v))
-
-#define ioreg16_read(a)  (*(volatile uint16_t *)(a))
-#define ioreg16_write(a,v)  (*(volatile uint16_t *)(a)=(v))
-
-#define ioreg8_read(a)  (*(volatile uint8_t *)(a))
-#define ioreg8_write(a,v)  (*(volatile uint8_t *)(a)=(v))
-
-#endif /* _MACHINE_REG_H */
Index: sys/arch/arm64/include/swi.h
===
RCS file: sys/arch/arm64/include/swi.h
diff -N sys/arch/arm64/include/swi.h
--- sys/arch/arm64/include/swi.h17 Dec 2016 23:38:33 -  1.1
+++ /dev/null   1 Jan 1970 00:00:00 -
@@ -1,23 +0,0 @@
-/* $OpenBSD: swi.h,v 1.1 2016/12/17 23:38:33 patrick Exp $ */
-/* $NetBSD: swi.h,v 1.1 2002/01/13 15:03:06 bjh21 Exp $*/
-
-/*
- * This file is in the Public Domain.
- * Ben Harris, 2002.
- */
-
-#ifndef _MACHINE_SWI_H_
-#define _MACHINE_SWI_H_
-
-#define SWI_OS_MASK0xf0
-#define SWI_OS_RISCOS  0x00
-#define SWI_OS_RISCIX  0x80
-#define SWI_OS_LINUX   0x90
-#define SWI_OS_NETBSD  0xa0
-#define SWI_OS_ARM 0xf0
-
-#define SWI_IMB0xf0
-#define SWI_IMBrange   0

Re: IPL_VM for `f_mtx'

2018-05-28 Thread Mark Kettenis
> Date: Mon, 28 May 2018 11:23:47 +0200
> From: Martin Pieuchot 
> 
> As found by tb@ and visa@, `f_mtx' need to block interrupts as long as
> it can be taken w/ and w/o the KERNEL_LOCK().  Otherwise a deadlock is
> possible if an interrupt tries to grab the KERNEL_LOCK().
> 
> I'm not switching to a rwlock because code paths are short, I don't
> want to introduce new sleeping points and in the long run we should
> be using SRPs or atomic operations for reference counts.
> 
> ok?

I suppose IPL_VM is the most sensible default for mutexes that need to
block all interrupts that might need the kernel lock.

ok kettenis@

> Index: kern/kern_descrip.c
> ===
> RCS file: /cvs/src/sys/kern/kern_descrip.c,v
> retrieving revision 1.158
> diff -u -p -r1.158 kern_descrip.c
> --- kern/kern_descrip.c   8 May 2018 09:03:58 -   1.158
> +++ kern/kern_descrip.c   28 May 2018 09:23:31 -
> @@ -957,7 +957,11 @@ restart:
>*/
>   numfiles++;
>   fp = pool_get(&file_pool, PR_WAITOK|PR_ZERO);
> - mtx_init(&fp->f_mtx, IPL_NONE);
> + /*
> +  * We need to block interrupts as long as `f_mtx' is being taken
> +  * with and without the KERNEL_LOCK().
> +  */
> + mtx_init(&fp->f_mtx, IPL_VM);
>   fp->f_iflags = FIF_LARVAL;
>   if ((fq = p->p_fd->fd_ofiles[0]) != NULL) {
>   LIST_INSERT_AFTER(fq, fp, f_list);
> 
> 



arm64/disksubr.c

2018-05-28 Thread Mark Kettenis
This has a hand-rolled readdisksector.  Replace it with a function
call like we do on other architectures.  Also remove an include that
isn't needed and isn't present on other architectures.

ok?


Index: arch/arm64/arm64/disksubr.c
===
RCS file: /cvs/src/sys/arch/arm64/arm64/disksubr.c,v
retrieving revision 1.2
diff -u -p -r1.2 disksubr.c
--- arch/arm64/arm64/disksubr.c 28 Feb 2017 10:49:37 -  1.2
+++ arch/arm64/arm64/disksubr.c 28 May 2018 13:55:31 -
@@ -32,7 +32,6 @@
  */
 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -110,15 +109,11 @@ writedisklabel(dev_t dev, void (*strat)(
goto done;
 
/* Read it in, slap the new label in, and write it back out */
-   bp->b_blkno = DL_BLKTOSEC(lp, partoff + DOS_LABELSECTOR) *
-   DL_BLKSPERSEC(lp);
-   offset = DL_BLKOFFSET(lp, partoff + DOS_LABELSECTOR);
-   bp->b_bcount = lp->d_secsize;
-   CLR(bp->b_flags, B_READ | B_WRITE | B_DONE);
-   SET(bp->b_flags, B_BUSY | B_READ | B_RAW);
-   (*strat)(bp);
-   if ((error = biowait(bp)) != 0)
+   error = readdisksector(bp, strat, lp, DL_BLKTOSEC(lp, partoff +
+   DOS_LABELSECTOR));
+   if (error)
goto done;
+   offset = DL_BLKOFFSET(lp, partoff + DOS_LABELSECTOR);
 
dlp = (struct disklabel *)(bp->b_data + offset);
*dlp = *lp;



Drop comcnspeed

2018-05-28 Thread Mark Kettenis
This variable is unused on arm64.  Inherited from armv7 where it still
functions somewhat.  I suppose this used to set the speed of the
serial console but nowadays it only sets the default speed that we use
when the device tree doesn't set it.  I propose to remove it on armv7
too.  Using 115200 as a default like we do on arm64 should work just
fine.  I've not seen any armv7 or arm64 hardware that uses 9600 by
default.  If we want a mechanism to set the default speed we should
have the bootloader tweak the device tree instead.

ok?


Index: arch/arm64/arm64/machdep.c
===
RCS file: /cvs/src/sys/arch/arm64/arm64/machdep.c,v
retrieving revision 1.34
diff -u -p -r1.34 machdep.c
--- arch/arm64/arm64/machdep.c  28 May 2018 19:39:15 -  1.34
+++ arch/arm64/arm64/machdep.c  28 May 2018 19:43:19 -
@@ -1135,7 +1135,6 @@ remap_efi_runtime(EFI_PHYSICAL_ADDRESS s
printf("SetVirtualAddressMap failed: %lu\n", status);
 }
 
-int comcnspeed = B115200;
 char bootargs[256];
 
 void
@@ -1194,12 +1193,6 @@ process_kernel_args(void)
break;
case 's':
fl |= RB_SINGLE;
-   break;
-   case '1':
-   comcnspeed = B115200;
-   break;
-   case '9':
-   comcnspeed = B9600;
break;
default:
printf("unknown option `%c'\n", *cp);



Re: IPL_VM for `f_mtx'

2018-05-28 Thread Mark Kettenis
> Date: Mon, 28 May 2018 12:24:22 +0200
> From: Mathieu - 
> 
> Mark Kettenis wrote:
> > > Date: Mon, 28 May 2018 11:23:47 +0200
> > > From: Martin Pieuchot 
> > > 
> > > As found by tb@ and visa@, `f_mtx' need to block interrupts as long as
> > > it can be taken w/ and w/o the KERNEL_LOCK().  Otherwise a deadlock is
> > > possible if an interrupt tries to grab the KERNEL_LOCK().
> > > 
> > > I'm not switching to a rwlock because code paths are short, I don't
> > > want to introduce new sleeping points and in the long run we should
> > > be using SRPs or atomic operations for reference counts.
> > > 
> > > ok?
> > 
> > I suppose IPL_VM is the most sensible default for mutexes that need to
> > block all interrupts that might need the kernel lock.
> > 
> > ok kettenis@
> 
> 
> Hello,
> 
> Wouldn't IPL_MPFLOOR be more appropriate? After all mutexes are already
> raising the ipl level to IPL_MPFLOOR (expect for IPL_NONE and above).

The problem is that IPL_MPFLOOR doesn't exist on all platforms.  Maybe
it should...

> > > Index: kern/kern_descrip.c
> > > ===
> > > RCS file: /cvs/src/sys/kern/kern_descrip.c,v
> > > retrieving revision 1.158
> > > diff -u -p -r1.158 kern_descrip.c
> > > --- kern/kern_descrip.c   8 May 2018 09:03:58 -   1.158
> > > +++ kern/kern_descrip.c   28 May 2018 09:23:31 -
> > > @@ -957,7 +957,11 @@ restart:
> > >*/
> > >   numfiles++;
> > >   fp = pool_get(&file_pool, PR_WAITOK|PR_ZERO);
> > > - mtx_init(&fp->f_mtx, IPL_NONE);
> > > + /*
> > > +  * We need to block interrupts as long as `f_mtx' is being taken
> > > +  * with and without the KERNEL_LOCK().
> > > +  */
> > > + mtx_init(&fp->f_mtx, IPL_VM);
> > >   fp->f_iflags = FIF_LARVAL;
> > >   if ((fq = p->p_fd->fd_ofiles[0]) != NULL) {
> > >   LIST_INSERT_AFTER(fq, fp, f_list);
> > > 
> > > 
> > 
> 



Remove comcnspeed and comcnmode on armv7

2018-05-30 Thread Mark Kettenis
Remove unused infrastructure.  After this we arm64 and armv7 com_fdt.c
are identical and I can move it into dev/fdt.

ok?


Index: armv7/armv7_machdep.c
===
RCS file: /cvs/src/sys/arch/armv7/armv7/armv7_machdep.c,v
retrieving revision 1.53
diff -u -p -r1.53 armv7_machdep.c
--- armv7/armv7_machdep.c   15 May 2018 11:11:35 -  1.53
+++ armv7/armv7_machdep.c   30 May 2018 13:23:36 -
@@ -207,16 +207,6 @@ void   consinit(void);
 
 bs_protos(bs_notimpl);
 
-#ifndef CONSPEED
-#define CONSPEED B115200   /* What u-boot */
-#endif
-#ifndef CONMODE
-#define CONMODE ((TTYDEF_CFLAG & ~(CSIZE | CSTOPB | PARENB)) | CS8) /* 8N1 */
-#endif
-
-int comcnspeed = CONSPEED;
-int comcnmode = CONMODE;
-
 int stdout_node;
 int stdout_speed;
 
Index: dev/com_fdt.c
===
RCS file: /cvs/src/sys/arch/armv7/dev/com_fdt.c,v
retrieving revision 1.13
diff -u -p -r1.13 com_fdt.c
--- dev/com_fdt.c   14 May 2018 19:25:54 -  1.13
+++ dev/com_fdt.c   30 May 2018 13:23:36 -
@@ -39,9 +39,6 @@ int   com_fdt_match(struct device *, void 
 void   com_fdt_attach(struct device *, struct device *, void *);
 intcom_fdt_intr_designware(void *);
 
-extern int comcnspeed;
-extern int comcnmode;
-
 struct cfattach com_fdt_ca = {
sizeof (struct com_softc), com_fdt_match, com_fdt_attach
 };
@@ -135,8 +132,7 @@ com_fdt_attach(struct device *parent, st
SET(sc->sc_hwflags, COM_HW_CONSOLE);
SET(sc->sc_swflags, COM_SW_SOFTCAR);
comconsfreq = sc->sc_frequency;
-   comconsrate = stdout_speed ? stdout_speed : comcnspeed;
-   comconscflag = comcnmode;
+   comconsrate = stdout_speed ? stdout_speed : B115200;
}
 
if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
Index: dev/pluart.c
===
RCS file: /cvs/src/sys/arch/armv7/dev/pluart.c,v
retrieving revision 1.7
diff -u -p -r1.7 pluart.c
--- dev/pluart.c19 Feb 2018 08:59:52 -  1.7
+++ dev/pluart.c30 May 2018 13:23:36 -
@@ -182,9 +182,6 @@ struct pluart_softc *pluart_sc(dev_t dev
 
 int pluart_intr(void *);
 
-extern int comcnspeed;
-extern int comcnmode;
-
 /* XXX - we imitate 'com' serial ports and take over their entry points */
 /* XXX: These belong elsewhere */
 cdev_decl(pluart);
@@ -214,7 +211,7 @@ pluart_init_cons(void)
if (fdt_get_reg(node, 0, ®))
return;
 
-   pluartcnattach(&armv7_bs_tag, reg.addr, comcnspeed, comcnmode);
+   pluartcnattach(&armv7_bs_tag, reg.addr, B115200, TTYDEF_CFLAG);
 }
 
 int
Index: exynos/exuart.c
===
RCS file: /cvs/src/sys/arch/armv7/exynos/exuart.c,v
retrieving revision 1.14
diff -u -p -r1.14 exuart.c
--- exynos/exuart.c 19 Feb 2018 08:59:52 -  1.14
+++ exynos/exuart.c 30 May 2018 13:23:36 -
@@ -108,9 +108,6 @@ struct exuart_softc *exuart_sc(dev_t dev
 
 int exuart_intr(void *);
 
-extern int comcnspeed;
-extern int comcnmode;
-
 /* XXX - we imitate 'com' serial ports and take over their entry points */
 /* XXX: These belong elsewhere */
 cdev_decl(exuart);
@@ -152,7 +149,7 @@ exuart_init_cons(void)
if (fdt_get_reg(node, 0, ®))
return;
 
-   exuartcnattach(&armv7_bs_tag, reg.addr, comcnspeed, comcnmode);
+   exuartcnattach(&armv7_bs_tag, reg.addr, B115200, TTYDEF_CFLAG);
 }
 
 int



Process-shared futexes

2018-06-01 Thread Mark Kettenis
The diff below changes our futex implementation to allow futexes that
are shared between processes.  Such futexes are a little bit tricky
since there is no guarantee that a futex is mapped at the same address
in each process.  To solve tis issue I adopted the strategy chosen by
FreeBSD.  Shared memory objects have a uvm object associated with
them.  So instead of using the virtual address I can use the offset
into that object.  Together with the a pointer to the object itself
that should form a unique ID for the futex.

In order to establish that we're dealing with shared memory we need to
lookup the mapping corresponding to the userspace address of the
futex.  That involves locking the map.  If we are worried about the
additional overhead we could introduce shared versions of the futex
operations and skip the lookup for non-shared (process-private) futexes.

These futexes could be used to implement support for the POSIX Thread
Process-Shared Synchronization option, i.e. the PTHREAD_PROCESS_SHARED
attribute for mutexes.  But I need these to make libxshmfence work on
OpenBSD, which is in turn needed to get DRI3 support working.

Making DRI3 support work is somewhat important.  We're currently using
DRI2 but Linux has moved to DRI3 and some of the DRI2-specific
codepaths in X are starting to rot.  DRI3 is also supposed to be more
secure than DRI2.  With DRI2, applications that can guess a 32-bit
handle can in principle access graphiucs buffers from other
applications.  With DRI3 graphics buffers are shared using file
descriptor passing which means that only processes that were passed
the file descriptor can access the graphics buffer.

Another feature of DRI3 is that graphics buffers can be shared between
graphics devices.  The idea there is that a GPU can render into a
buffer which is then shared with the Intel CPU graphics which can then
display it on the screen.  But my initial implementation won't support
that.

Thoughts?  Especially on whether we want to distinguish between
process-shared and process-private futexes!


Index: kern/sys_futex.c
===
RCS file: /cvs/src/sys/kern/sys_futex.c,v
retrieving revision 1.7
diff -u -p -r1.7 sys_futex.c
--- kern/sys_futex.c24 Apr 2018 17:19:35 -  1.7
+++ kern/sys_futex.c1 Jun 2018 15:50:17 -
@@ -31,6 +31,8 @@
 #include 
 #endif
 
+#include 
+
 /*
  * Atomicity is only needed on MULTIPROCESSOR kernels.  Fall back on
  * copyin(9) until non-MULTIPROCESSOR architectures have a copyin32(9)
@@ -46,6 +48,8 @@
 struct futex {
LIST_ENTRY(futex)ft_list;   /* list of all futexes */
TAILQ_HEAD(, proc)   ft_threads;/* sleeping queue */
+   struct uvm_object   *ft_obj;
+   voff_t   ft_offset;
uint32_t*ft_uaddr;  /* userspace address */
pid_tft_pid;/* process identifier */
unsigned int ft_refcnt; /* # of references */
@@ -130,8 +134,22 @@ struct futex *
 futex_get(uint32_t *uaddr, int flag)
 {
struct proc *p = curproc;
+   vm_map_t map = &p->p_vmspace->vm_map;
+   vm_map_entry_t entry;
+   struct uvm_object *obj = NULL;
+   voff_t offset = 0;
struct futex *f;
 
+   vm_map_lock_read(map);
+   if (uvm_map_lookup_entry(map, (vaddr_t)uaddr, &entry)) {
+   if (entry->object.uvm_obj &&
+   entry->inheritance == MAP_INHERIT_SHARE) {
+   obj = entry->object.uvm_obj;
+   offset = entry->offset + ((vaddr_t)uaddr - 
entry->start);
+   }
+   }
+   vm_map_unlock_read(map);
+
rw_assert_wrlock(&ftlock);
 
LIST_FOREACH(f, &ftlist, ft_list) {
@@ -139,6 +157,10 @@ futex_get(uint32_t *uaddr, int flag)
f->ft_refcnt++;
break;
}
+   if (f->ft_obj == obj && f->ft_offset == offset) {
+   f->ft_refcnt++;
+   break;
+   }
}
 
if ((f == NULL) && (flag & FT_CREATE)) {
@@ -146,10 +168,15 @@ futex_get(uint32_t *uaddr, int flag)
 * We rely on the rwlock to ensure that no other thread
 * create the same futex.
 */
-   f = pool_get(&ftpool, PR_WAITOK);
+   f = pool_get(&ftpool, PR_WAITOK | PR_ZERO);
TAILQ_INIT(&f->ft_threads);
-   f->ft_uaddr = uaddr;
-   f->ft_pid = p->p_p->ps_pid;
+   if (obj) {
+   f->ft_obj = obj;
+   f->ft_offset = offset;
+   } else {
+   f->ft_uaddr = uaddr;
+   f->ft_pid = p->p_p->ps_pid;
+   }
f->ft_refcnt = 1;
LIST_INSERT_HEAD(&ftlist, f, ft_list);
}



Re: Process-shared futexes

2018-06-02 Thread Mark Kettenis
> Date: Sat, 2 Jun 2018 12:04:16 +0200
> From: Martin Pieuchot 
> 
> On 01/06/18(Fri) 19:13, Mark Kettenis wrote:
> > The diff below changes our futex implementation to allow futexes that
> > are shared between processes.  Such futexes are a little bit tricky
> > since there is no guarantee that a futex is mapped at the same address
> > in each process.  To solve tis issue I adopted the strategy chosen by
> > FreeBSD.  Shared memory objects have a uvm object associated with
> > them.  So instead of using the virtual address I can use the offset
> > into that object.  Together with the a pointer to the object itself
> > that should form a unique ID for the futex.
> 
> Nice.
> 
> > In order to establish that we're dealing with shared memory we need to
> > lookup the mapping corresponding to the userspace address of the
> > futex.  That involves locking the map.  If we are worried about the
> > additional overhead we could introduce shared versions of the futex
> > operations and skip the lookup for non-shared (process-private) futexes.
> > 
> > These futexes could be used to implement support for the POSIX Thread
> > Process-Shared Synchronization option, i.e. the PTHREAD_PROCESS_SHARED
> > attribute for mutexes.  But I need these to make libxshmfence work on
> > OpenBSD, which is in turn needed to get DRI3 support working.
> > 
> > Making DRI3 support work is somewhat important.  We're currently using
> > DRI2 but Linux has moved to DRI3 and some of the DRI2-specific
> > codepaths in X are starting to rot.  DRI3 is also supposed to be more
> > secure than DRI2.  With DRI2, applications that can guess a 32-bit
> > handle can in principle access graphiucs buffers from other
> > applications.  With DRI3 graphics buffers are shared using file
> > descriptor passing which means that only processes that were passed
> > the file descriptor can access the graphics buffer.
> > 
> > Another feature of DRI3 is that graphics buffers can be shared between
> > graphics devices.  The idea there is that a GPU can render into a
> > buffer which is then shared with the Intel CPU graphics which can then
> > display it on the screen.  But my initial implementation won't support
> > that.
> > 
> > Thoughts?  Especially on whether we want to distinguish between
> > process-shared and process-private futexes!
> 
> I'd prefer if we could do the distinction.  Would it be enough to pass
> a flag to futex_get()?

More or less.  The question is what what we should do if someone asks
for a process-shared futex in memory that isn't shared.  Should we
automatically create a process-private futex?  Or should this result
in an error?

I suspect that people expect PTHREAD_PROCESS_SHARED mutexes to work
even if they're not created in shared memory.  So a failure to create
a process-shared futex should probably fall through into the
process-private case.

Turns out Linux already has a FUTEX_PRIVATE_FLAG and
FUTEX_WAIT_PRIVATE, FUTEX_WAKE_PRIVATE and FUTEX_REQUEUE_PRIVATE
operations.  So I'll just stick to that API.

> > Index: kern/sys_futex.c
> > ===
> > RCS file: /cvs/src/sys/kern/sys_futex.c,v
> > retrieving revision 1.7
> > diff -u -p -r1.7 sys_futex.c
> > --- kern/sys_futex.c24 Apr 2018 17:19:35 -  1.7
> > +++ kern/sys_futex.c1 Jun 2018 15:50:17 -
> > @@ -31,6 +31,8 @@
> >  #include 
> >  #endif
> >  
> > +#include 
> > +
> >  /*
> >   * Atomicity is only needed on MULTIPROCESSOR kernels.  Fall back on
> >   * copyin(9) until non-MULTIPROCESSOR architectures have a copyin32(9)
> > @@ -46,6 +48,8 @@
> >  struct futex {
> > LIST_ENTRY(futex)ft_list;   /* list of all futexes */
> > TAILQ_HEAD(, proc)   ft_threads;/* sleeping queue */
> > +   struct uvm_object   *ft_obj;
> > +   voff_t   ft_offset;
> > uint32_t*ft_uaddr;  /* userspace address */
> > pid_tft_pid;/* process identifier */
> > unsigned int ft_refcnt; /* # of references */
> > @@ -130,8 +134,22 @@ struct futex *
> >  futex_get(uint32_t *uaddr, int flag)
> >  {
> > struct proc *p = curproc;
> > +   vm_map_t map = &p->p_vmspace->vm_map;
> > +   vm_map_entry_t entry;
> > +   struct uvm_object *obj = NULL;
> > +   voff_t offset = 0;
> > struct futex *f;
> >  
> > +   vm_map_lock_read(map);
> > +   if (uvm_map_lookup_entry(map, (vaddr_t)uad

Re: Remove unused C3 values (VIA)

2018-06-02 Thread Mark Kettenis
> Date: Sat, 2 Jun 2018 11:30:15 +
> From: Visa Hankala 
> 
> On Sat, Jun 02, 2018 at 01:00:05PM +0200, Frederic Cambus wrote:
> > Hi tech@,
> > 
> > Here is a diff to remove unused C3 values.
> > 
> > Comments? OK?
> 
> I would keep the definitions because they can at least serve as a weak
> form of documentation about the hardware. For example,
> C3_CRYPT_CWLO_ALG_M indicates what bits specify the algorithm, which
> in turn helps one to understand the value of C3_CRYPT_CWLO_ALG_AES.

+1



armv7 lld fix

2018-06-02 Thread Mark Kettenis
Diff below works around a crash provoked by the

/DISCARD/ :
{
*(.ARM.exidx)
}

fragment in the kernel linker script.  It seems this issue is already
fixed upstream in a different way.  But backporting that fix isn't
trivial.

ok?


Index: gnu/llvm/tools/lld/ELF/SyntheticSections.cpp
===
RCS file: /cvs/src/gnu/llvm/tools/lld/ELF/SyntheticSections.cpp,v
retrieving revision 1.7
diff -u -p -r1.7 SyntheticSections.cpp
--- gnu/llvm/tools/lld/ELF/SyntheticSections.cpp6 Apr 2018 14:38:28 
-   1.7
+++ gnu/llvm/tools/lld/ELF/SyntheticSections.cpp2 Jun 2018 12:16:06 
-
@@ -2571,6 +2571,9 @@ void ARMExidxSentinelSection::writeTo(ui
 // The sentinel has to be removed if there are no other .ARM.exidx entries.
 bool ARMExidxSentinelSection::empty() const {
   OutputSection *OS = getParent();
+  if (!OS)
+return false;
+
   for (auto *B : OS->SectionCommands)
 if (auto *ISD = dyn_cast(B))
   for (auto *S : ISD->Sections)



Re: Process-shared futexes

2018-06-02 Thread Mark Kettenis
> Date: Sat, 2 Jun 2018 12:42:14 +0200 (CEST)
> From: Mark Kettenis 
> 
> > Date: Sat, 2 Jun 2018 12:04:16 +0200
> > From: Martin Pieuchot 
> > 
> > On 01/06/18(Fri) 19:13, Mark Kettenis wrote:
> > > The diff below changes our futex implementation to allow futexes that
> > > are shared between processes.  Such futexes are a little bit tricky
> > > since there is no guarantee that a futex is mapped at the same address
> > > in each process.  To solve tis issue I adopted the strategy chosen by
> > > FreeBSD.  Shared memory objects have a uvm object associated with
> > > them.  So instead of using the virtual address I can use the offset
> > > into that object.  Together with the a pointer to the object itself
> > > that should form a unique ID for the futex.
> > 
> > Nice.
> > 
> > > In order to establish that we're dealing with shared memory we need to
> > > lookup the mapping corresponding to the userspace address of the
> > > futex.  That involves locking the map.  If we are worried about the
> > > additional overhead we could introduce shared versions of the futex
> > > operations and skip the lookup for non-shared (process-private) futexes.
> > > 
> > > These futexes could be used to implement support for the POSIX Thread
> > > Process-Shared Synchronization option, i.e. the PTHREAD_PROCESS_SHARED
> > > attribute for mutexes.  But I need these to make libxshmfence work on
> > > OpenBSD, which is in turn needed to get DRI3 support working.
> > > 
> > > Making DRI3 support work is somewhat important.  We're currently using
> > > DRI2 but Linux has moved to DRI3 and some of the DRI2-specific
> > > codepaths in X are starting to rot.  DRI3 is also supposed to be more
> > > secure than DRI2.  With DRI2, applications that can guess a 32-bit
> > > handle can in principle access graphiucs buffers from other
> > > applications.  With DRI3 graphics buffers are shared using file
> > > descriptor passing which means that only processes that were passed
> > > the file descriptor can access the graphics buffer.
> > > 
> > > Another feature of DRI3 is that graphics buffers can be shared between
> > > graphics devices.  The idea there is that a GPU can render into a
> > > buffer which is then shared with the Intel CPU graphics which can then
> > > display it on the screen.  But my initial implementation won't support
> > > that.
> > > 
> > > Thoughts?  Especially on whether we want to distinguish between
> > > process-shared and process-private futexes!
> > 
> > I'd prefer if we could do the distinction.  Would it be enough to pass
> > a flag to futex_get()?
> 
> More or less.  The question is what what we should do if someone asks
> for a process-shared futex in memory that isn't shared.  Should we
> automatically create a process-private futex?  Or should this result
> in an error?
> 
> I suspect that people expect PTHREAD_PROCESS_SHARED mutexes to work
> even if they're not created in shared memory.  So a failure to create
> a process-shared futex should probably fall through into the
> process-private case.
> 
> Turns out Linux already has a FUTEX_PRIVATE_FLAG and
> FUTEX_WAIT_PRIVATE, FUTEX_WAKE_PRIVATE and FUTEX_REQUEUE_PRIVATE
> operations.  So I'll just stick to that API.

So here is an implementation of that APU.  After this gets committed
we can change libc to use the _PRIVATE versions of the mutex
operations.  I already verified that that works.

ok?


Index: kern/sys_futex.c
===
RCS file: /cvs/src/sys/kern/sys_futex.c,v
retrieving revision 1.7
diff -u -p -r1.7 sys_futex.c
--- kern/sys_futex.c24 Apr 2018 17:19:35 -  1.7
+++ kern/sys_futex.c2 Jun 2018 16:36:31 -
@@ -31,6 +31,8 @@
 #include 
 #endif
 
+#include 
+
 /*
  * Atomicity is only needed on MULTIPROCESSOR kernels.  Fall back on
  * copyin(9) until non-MULTIPROCESSOR architectures have a copyin32(9)
@@ -46,21 +48,23 @@
 struct futex {
LIST_ENTRY(futex)ft_list;   /* list of all futexes */
TAILQ_HEAD(, proc)   ft_threads;/* sleeping queue */
-   uint32_t*ft_uaddr;  /* userspace address */
+   struct uvm_object   *ft_obj;/* UVM object */
+   voff_t   ft_off;/* UVM offset */
pid_tft_pid;/* process identifier */
unsigned int ft_refcnt; /* # of references */
 };
 
 /* Syscall helpers. */
-int futex_wait(uint32_t *, uint32_t, const stru

OpenBSD will never run on XScale again

2018-06-03 Thread Mark Kettenis
Time to get rid of these #ifdef __XSCALE__ bits.  No binary change.

ok?


Index: arch/arm/arm/bcopy_page.S
===
RCS file: /cvs/src/sys/arch/arm/arm/bcopy_page.S,v
retrieving revision 1.1
diff -u -p -r1.1 bcopy_page.S
--- arch/arm/arm/bcopy_page.S   1 Feb 2004 05:09:48 -   1.1
+++ arch/arm/arm/bcopy_page.S   3 Jun 2018 17:54:36 -
@@ -44,8 +44,6 @@
 
 #include "assym.h"
 
-#ifndef __XSCALE__
-
 /* #define BIG_LOOPS */
 
 /*
@@ -178,99 +176,3 @@ ENTRY(bzero_page)
bne 1b
 
ldmfd   sp!, {r4-r8, pc}
-
-#else  /* __XSCALE__ */
-
-/*
- * XSCALE version of bcopy_page
- */
-ENTRY(bcopy_page)
-   pld [r0]
-   stmfd   sp!, {r4, r5}
-   mov ip, #32
-   ldr r2, [r0], #0x04 /* 0x00 */
-   ldr r3, [r0], #0x04 /* 0x04 */
-1: pld [r0, #0x18] /* Prefetch 0x20 */
-   ldr r4, [r0], #0x04 /* 0x08 */
-   ldr r5, [r0], #0x04 /* 0x0c */
-   strdr2, [r1], #0x08
-   ldr r2, [r0], #0x04 /* 0x10 */
-   ldr r3, [r0], #0x04 /* 0x14 */
-   strdr4, [r1], #0x08
-   ldr r4, [r0], #0x04 /* 0x18 */
-   ldr r5, [r0], #0x04 /* 0x1c */
-   strdr2, [r1], #0x08
-   ldr r2, [r0], #0x04 /* 0x20 */
-   ldr r3, [r0], #0x04 /* 0x24 */
-   pld [r0, #0x18] /* Prefetch 0x40 */
-   strdr4, [r1], #0x08
-   ldr r4, [r0], #0x04 /* 0x28 */
-   ldr r5, [r0], #0x04 /* 0x2c */
-   strdr2, [r1], #0x08
-   ldr r2, [r0], #0x04 /* 0x30 */
-   ldr r3, [r0], #0x04 /* 0x34 */
-   strdr4, [r1], #0x08
-   ldr r4, [r0], #0x04 /* 0x38 */
-   ldr r5, [r0], #0x04 /* 0x3c */
-   strdr2, [r1], #0x08
-   ldr r2, [r0], #0x04 /* 0x40 */
-   ldr r3, [r0], #0x04 /* 0x44 */
-   pld [r0, #0x18] /* Prefetch 0x60 */
-   strdr4, [r1], #0x08
-   ldr r4, [r0], #0x04 /* 0x48 */
-   ldr r5, [r0], #0x04 /* 0x4c */
-   strdr2, [r1], #0x08
-   ldr r2, [r0], #0x04 /* 0x50 */
-   ldr r3, [r0], #0x04 /* 0x54 */
-   strdr4, [r1], #0x08
-   ldr r4, [r0], #0x04 /* 0x58 */
-   ldr r5, [r0], #0x04 /* 0x5c */
-   strdr2, [r1], #0x08
-   ldr r2, [r0], #0x04 /* 0x60 */
-   ldr r3, [r0], #0x04 /* 0x64 */
-   pld [r0, #0x18] /* Prefetch 0x80 */
-   strdr4, [r1], #0x08
-   ldr r4, [r0], #0x04 /* 0x68 */
-   ldr r5, [r0], #0x04 /* 0x6c */
-   strdr2, [r1], #0x08
-   ldr r2, [r0], #0x04 /* 0x70 */
-   ldr r3, [r0], #0x04 /* 0x74 */
-   strdr4, [r1], #0x08
-   ldr r4, [r0], #0x04 /* 0x78 */
-   ldr r5, [r0], #0x04 /* 0x7c */
-   strdr2, [r1], #0x08
-   subsip, ip, #0x01
-   ldrgt   r2, [r0], #0x04 /* 0x80 */
-   ldrgt   r3, [r0], #0x04 /* 0x84 */
-   strdr4, [r1], #0x08
-   bgt 1b
-   ldmfd   sp!, {r4, r5}
-   mov pc, lr
-
-/*
- * XSCALE version of bzero_page
- */
-ENTRY(bzero_page)
-   mov r1, #PAGE_SIZE
-   mov r2, #0
-   mov r3, #0
-1: strdr2, [r0], #8/* 32 */
-   strdr2, [r0], #8
-   strdr2, [r0], #8
-   strdr2, [r0], #8
-   strdr2, [r0], #8/* 64 */
-   strdr2, [r0], #8
-   strdr2, [r0], #8
-   strdr2, [r0], #8
-   strdr2, [r0], #8/* 96 */
-   strdr2, [r0], #8
-   strdr2, [r0], #8
-   strdr2, [r0], #8
-   strdr2, [r0], #8/* 128 */
-   strdr2, [r0], #8
-   strdr2, [r0], #8
-   strdr2, [r0], #8
-   subsr1, r1, #128
-   bne 1b
-   mov pc, lr
-#endif /* __XSCALE__ */
Index: arch/arm/arm/bcopyinout.S
===
RCS file: /cvs/src/sys/arch/arm/arm/bcopyinout.S,v
retrieving revision 1.7
diff -u -p -r1.7 bcopyinout.S
--- arch/arm/arm/bcopyinout.S   6 Jan 2017 00:06:02 -   1.7
+++ arch/arm/arm/bcopyinout.S   3 Jun 2018 17:54:36 -
@@ -41,10 +41,6 @@
 #include 
 #include 
 
-#ifdef __XSCALE__
-#include "bcopyinout_xscale.S"
-#else
-
.text
.align  2
 
@@ -59,13 +55,6 @@
 #define SAVE_REGS  stmfd   sp!, {r4-r11}
 #define RESTORE_REGS   ldmfd   sp!, {r4-r11}

-#if defined(__XSCALE__)
-#define HELLOCPP #
-#define PREFETCH(rx,o) pld [ rx , HELLOCPP (o) ]
-#else
-#define PREFETCH(rx,o)
-#endif
-
 /*
  * r0 = user space address
  * r1 = kernel space address
@@ -92,9 +81,6 @@ ENTRY(copyin)
adr r3, .Lcopyfault
   

Make libc/libpthread use process-private futexes

2018-06-03 Thread Mark Kettenis
Now that the kernel distinguishes between process-shared and
process-private futexes make libc/libpthread use process-private ones.

ok?


Index: lib/libc/thread/synch.h
===
RCS file: /cvs/src/lib/libc/thread/synch.h,v
retrieving revision 1.2
diff -u -p -r1.2 synch.h
--- lib/libc/thread/synch.h 5 Sep 2017 02:40:54 -   1.2
+++ lib/libc/thread/synch.h 3 Jun 2018 21:58:58 -
@@ -22,14 +22,14 @@
 static inline int
 _wake(volatile uint32_t *p, int n)
 {
-   return futex(p, FUTEX_WAKE, n, NULL, NULL);
+   return futex(p, FUTEX_WAKE_PRIVATE, n, NULL, NULL);
 }
 
 static inline void
 _wait(volatile uint32_t *p, int val)
 {
while (*p != (uint32_t)val)
-   futex(p, FUTEX_WAIT, val, NULL, NULL);
+   futex(p, FUTEX_WAIT_PRIVATE, val, NULL, NULL);
 }
 
 static inline int
@@ -38,7 +38,7 @@ _twait(volatile uint32_t *p, int val, cl
struct timespec rel;
 
if (abs == NULL)
-   return futex(p, FUTEX_WAIT, val, NULL, NULL);
+   return futex(p, FUTEX_WAIT_PRIVATE, val, NULL, NULL);
 
if (abs->tv_nsec >= 10 || clock_gettime(clockid, &rel))
return (EINVAL);
@@ -51,11 +51,11 @@ _twait(volatile uint32_t *p, int val, cl
if (rel.tv_sec < 0)
return (ETIMEDOUT);
 
-   return futex(p, FUTEX_WAIT, val, &rel, NULL);
+   return futex(p, FUTEX_WAIT_PRIVATE, val, &rel, NULL);
 }
 
 static inline int
 _requeue(volatile uint32_t *p, int n, int m, volatile uint32_t *q)
 {
-   return futex(p, FUTEX_REQUEUE, n, (void *)(long)m, q);
+   return futex(p, FUTEX_REQUEUE_PRIVATE, n, (void *)(long)m, q);
 }



Re: drop unused BUMPTIME macro

2018-06-04 Thread Mark Kettenis
> Date: Mon, 4 Jun 2018 12:20:29 -0500
> From: Scott Cheloha 
> 
> miod@ dropped the last usage of BUMPTIME circa 5.3.
> 
> ok?

ok kettenis@

> Index: sys/kern/kern_clock.c
> ===
> RCS file: /cvs/src/sys/kern/kern_clock.c,v
> retrieving revision 1.94
> diff -u -p -r1.94 kern_clock.c
> --- sys/kern/kern_clock.c 14 May 2018 12:31:21 -  1.94
> +++ sys/kern/kern_clock.c 4 Jun 2018 16:38:29 -
> @@ -79,20 +79,6 @@
>   * profhz/stathz for statistics.  (For profiling, every tick counts.)
>   */
>  
> -/*
> - * Bump a timeval by a small number of usec's.
> - */
> -#define BUMPTIME(t, usec) { \
> - volatile struct timeval *tp = (t); \
> - long us; \
> - \
> - tp->tv_usec = us = tp->tv_usec + (usec); \
> - if (us >= 100) { \
> - tp->tv_usec = us - 100; \
> - tp->tv_sec++; \
> - } \
> -}
> -
>  int  stathz;
>  int  schedhz;
>  int  profhz;
> 
> 



Re: kqueue: move members from filedesc to kqueue

2018-06-15 Thread Mark Kettenis
> Date: Fri, 15 Jun 2018 09:59:47 +0200
> From: Anton Lindqvist 
> 
> On Tue, Jun 12, 2018 at 09:00:14PM +0200, Anton Lindqvist wrote:
> > Hi,
> > This diff moves the kqueue related members from struct filedesc to
> > struct kqueue with the prime motivation of fixing a panic in
> > knote_processexit() that can occur when the filedesc is gone.
> > Since filedesc is no longer shared between kqueues belong to the same
> > process, I added a list of the current kqueues to struct process. This
> > list is used in knote_closefd() in order to remove all knotes using the
> > given fd as its ident from all kqueues belonging to the given process.
> > 
> > Similiar work has been done in both FreeBSD[1] and DragonFlyBSD[2].
> > 
> > Testing would be much appreciated. Not asking for anything particular,
> > just apply the diff and exercise the kernel with your daily tasks.
> > 
> > [1] 
> > https://github.com/freebsd/freebsd/commit/bc1805c6e871c178d0b6516c3baa774ffd77224a
> > [2] 
> > http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/ccafe911a3aa55fd5262850ecfc5765cd31a56a2
> 
> Me and tb@ have been running this diff without problems. It also
> survived a `make release' and upgrade. Already got an ok from visa@,
> anyone else that can comment on the code and hopefully give another ok?

The kqueue regression tests still pass isn't it?

ok kettenis@

> > Index: kern/kern_descrip.c
> > ===
> > RCS file: /cvs/src/sys/kern/kern_descrip.c,v
> > retrieving revision 1.164
> > diff -u -p -r1.164 kern_descrip.c
> > --- kern/kern_descrip.c 5 Jun 2018 09:29:05 -   1.164
> > +++ kern/kern_descrip.c 12 Jun 2018 17:11:44 -
> > @@ -650,8 +650,7 @@ finishdup(struct proc *p, struct file *f
> > *retval = new;
> >  
> > if (oldfp != NULL) {
> > -   if (new < fdp->fd_knlistsize)
> > -   knote_fdclose(p, new);
> > +   knote_fdclose(p, new);
> > closef(oldfp, p);
> > }
> >  
> > @@ -686,8 +685,7 @@ fdrelease(struct proc *p, int fd)
> > FREF(fp);
> > *fpp = NULL;
> > fd_unused(fdp, fd);
> > -   if (fd < fdp->fd_knlistsize)
> > -   knote_fdclose(p, fd);
> > +   knote_fdclose(p, fd);
> > return (closef(fp, p));
> >  }
> >  
> > @@ -999,7 +997,6 @@ fdinit(void)
> > newfdp->fd_fd.fd_nfiles = NDFILE;
> > newfdp->fd_fd.fd_himap = newfdp->fd_dhimap;
> > newfdp->fd_fd.fd_lomap = newfdp->fd_dlomap;
> > -   newfdp->fd_fd.fd_knlistsize = -1;
> >  
> > newfdp->fd_fd.fd_freefile = 0;
> > newfdp->fd_fd.fd_lastfile = 0;
> > @@ -1129,8 +1126,6 @@ fdfree(struct proc *p)
> > vrele(fdp->fd_cdir);
> > if (fdp->fd_rdir)
> > vrele(fdp->fd_rdir);
> > -   free(fdp->fd_knlist, M_TEMP, fdp->fd_knlistsize * sizeof(struct klist));
> > -   hashfree(fdp->fd_knhash, KN_HASHSIZE, M_TEMP);
> > pool_put(&fdesc_pool, fdp);
> >  }
> >  
> > Index: kern/kern_event.c
> > ===
> > RCS file: /cvs/src/sys/kern/kern_event.c,v
> > retrieving revision 1.91
> > diff -u -p -r1.91 kern_event.c
> > --- kern/kern_event.c   5 Jun 2018 09:29:05 -   1.91
> > +++ kern/kern_event.c   12 Jun 2018 17:11:44 -
> > @@ -80,8 +80,8 @@ struct fileops kqueueops = {
> > .fo_close   = kqueue_close
> >  };
> >  
> > -void   knote_attach(struct knote *kn, struct filedesc *fdp);
> > -void   knote_drop(struct knote *kn, struct proc *p, struct filedesc 
> > *fdp);
> > +void   knote_attach(struct knote *kn);
> > +void   knote_drop(struct knote *kn, struct proc *p);
> >  void   knote_enqueue(struct knote *kn);
> >  void   knote_dequeue(struct knote *kn);
> >  #define knote_alloc() ((struct knote *)pool_get(&knote_pool, PR_WAITOK))
> > @@ -152,9 +152,13 @@ KQREF(struct kqueue *kq)
> >  void
> >  KQRELE(struct kqueue *kq)
> >  {
> > -   if (--kq->kq_refs == 0) {
> > -   pool_put(&kqueue_pool, kq);
> > -   }
> > +   if (--kq->kq_refs > 0)
> > +   return;
> > +
> > +   LIST_REMOVE(kq, kq_next);
> > +   free(kq->kq_knlist, M_TEMP, kq->kq_knlistsize * sizeof(struct klist));
> > +   hashfree(kq->kq_knhash, KN_HASHSIZE, M_TEMP);
> > +   pool_put(&kqueue_pool, kq);
> >  }
> >  
> >  void kqueue_init(void);
> > @@ -453,10 +457,9 @@ sys_kqueue(struct proc *p, void *v, regi
> > fp->f_data = kq;
> > KQREF(kq);
> > *retval = fd;
> > -   if (fdp->fd_knlistsize < 0)
> > -   fdp->fd_knlistsize = 0; /* this process has a kq */
> > kq->kq_fdp = fdp;
> > FILE_SET_MATURE(fp, p);
> > +   LIST_INSERT_HEAD(&p->p_p->ps_kqlist, kq, kq_next);
> > return (0);
> >  }
> >  
> > @@ -583,19 +586,19 @@ kqueue_register(struct kqueue *kq, struc
> > if ((fp = fd_getfile(fdp, kev->ident)) == NULL)
> > return (EBADF);
> >  
> > -   if (kev->ident < fdp->fd_knlistsize) {
> > -   SLIST_FOREACH(kn, &fdp->fd_knlis

Re: ksh "clear-screen" editing command

2018-06-16 Thread Mark Kettenis
> From: "Todd C. Miller" 
> Date: Sat, 16 Jun 2018 06:37:03 -0600
> 
> On Tue, 12 Jun 2018 02:35:57 +0200, Alexander Hall wrote:
> 
> > The diff below uses system(3) to call /usr/bin/clear, fiddling with 
> > *env() to make sure the current TERM value is propagated. The error 
> > handling is deliberately sparse, since I don't know what the reasonable 
> > error actions would be.
> >
> > It's quite possible there already exists a better function to call 
> > within the ksh code already, but I was unable to figure out which if so.
> 
> Using system() within ksh seems wrong.  How about this instead?

To e honest, I find the whole idea of invoking an external program to
clear the screen insane.

> Index: bin/ksh/emacs.c
> ===
> RCS file: /cvs/src/bin/ksh/emacs.c,v
> retrieving revision 1.84
> diff -u -p -u -r1.84 emacs.c
> --- bin/ksh/emacs.c   16 Jan 2018 17:17:18 -  1.84
> +++ bin/ksh/emacs.c   16 Jun 2018 12:31:59 -
> @@ -146,6 +146,7 @@ static intisu8cont(unsigned char);
>  /* proto's for keybindings */
>  static int   x_abort(int);
>  static int   x_beg_hist(int);
> +static int   x_clear_screen(int);
>  static int   x_comp_comm(int);
>  static int   x_comp_file(int);
>  static int   x_complete(int);
> @@ -202,6 +203,7 @@ static intx_debug_info(int);
>  static const struct x_ftab x_ftab[] = {
>   { x_abort,  "abort",0 },
>   { x_beg_hist,   "beginning-of-history", 0 },
> + { x_clear_screen,   "clear-screen", 0 },
>   { x_comp_comm,  "complete-command", 0 },
>   { x_comp_file,  "complete-file",0 },
>   { x_complete,   "complete", 0 },
> @@ -1004,12 +1006,19 @@ x_draw_line(int c)
>  {
>   x_redraw(-1);
>   return KSTD;
> +}
>  
> +static int
> +x_clear_screen(int c)
> +{
> + x_redraw(-2);
> + return KSTD;
>  }
>  
> -/* Redraw (part of) the line.  If limit is < 0, the everything is redrawn
> - * on a NEW line, otherwise limit is the screen column up to which needs
> - * redrawing.
> +/* Redraw (part of) the line.
> + * A non-negative limit is the screen column up to which needs
> + * redrawing. A limit of -1 redraws on a new line, while a limit
> + * of -2 (attempts to) clear the screen.
>   */
>  static void
>  x_redraw(int limit)
> @@ -1018,9 +1027,20 @@ x_redraw(int limit)
>   char*cp;
>  
>   x_adj_ok = 0;
> - if (limit == -1)
> + if (limit == -2) {
> + char *term = str_val(global("TERM"));
> + int ret = -1;
> + if (term && *term) {
> + Source *sold = source;
> + ret = command("/usr/bin/clear", 0);
> + source = sold;
> + }
> + if (ret != 0)
> + x_e_putc('\n');
> + }
> + else if (limit == -1)
>   x_e_putc('\n');
> - else
> + else if (limit >= 0)
>   x_e_putc('\r');
>   x_flush();
>   if (xbp == xbuf) {
> Index: bin/ksh/ksh.1
> ===
> RCS file: /cvs/src/bin/ksh/ksh.1,v
> retrieving revision 1.200
> diff -u -p -u -r1.200 ksh.1
> --- bin/ksh/ksh.1 30 May 2018 21:20:52 -  1.200
> +++ bin/ksh/ksh.1 16 Jun 2018 12:29:34 -
> @@ -4690,6 +4690,10 @@ Moves the cursor to the beginning of the
>  Uppercase the first character in the next
>  .Ar n
>  words, leaving the cursor past the end of the last word.
> +.It clear-screen:
> +Attempts to clears the screen by invoking
> +.Xr clear 1
> +and redraws the prompt and current input line.
>  .It comment: ^[#
>  If the current line does not begin with a comment character, one is added at
>  the beginning of the line and the line is entered (as if return had been
> 
> 



Re: ksh "clear-screen" editing command

2018-06-16 Thread Mark Kettenis
> From: "Todd C. Miller" 
> Date: Sat, 16 Jun 2018 06:53:38 -0600
> 
> On Sat, 16 Jun 2018 14:50:40 +0200, Mark Kettenis wrote:
> 
> > To be honest, I find the whole idea of invoking an external program to
> > clear the screen insane.
> 
> Do you have an alternative that doesn't require linking ksh with
> curses?

Simply drop the idea of implementing clear-screen?



Re: fdinsert(), take 3

2018-06-16 Thread Mark Kettenis
> Date: Thu, 14 Jun 2018 14:28:07 +0200
> From: Martin Pieuchot 
> 
> This version should fixes the previous issue where LARVAL files were
> incorrectly accounted in find_last_set() resulting in a panic() in
> fd_unused().
> 
> If you haven't read the previous explanations, the idea of this diff
> is to publish file descriptors only when they are completely setup.
> This will allow us to serialize access to file descriptors in a mp-safe
> way, which is the last requirement for unlock most of the socket-related
> syscalls.
> 
> The important point of this diff is that we don't store on the descriptor
> itself the fact that it isn't ready yet (LARVAL).  Otherwise we have a
> chicken & egg problem for reference counting.  As pointed by Mathieu
> Masson other BSDs do that by using a new structure for open files.  We
> might want to do that later when we'll turn these functions mp-safe :)
> For now, using the existing bitmask is good enough.
> 
> Here are previous explanations:
>   https://marc.info/?l=openbsd-tech&m=152579630904328&w=2
>   https://marc.info/?l=openbsd-tech&m=152750590114899&w=2
> 
> Please test & report as usual.
> 
> Ok?

Sorry, but no, I don't think this diff is ok.  Your new code inserts
the struct file into the linked list of all open files on fdinsert().
However, there is code that bails out and calls closef() before that
fdinsert() happens.  For exacmple in kern_exec.c:sys_execve() and in
sys_pipe.c:dopipe() (if the 2nd falloc() call fails).

I really think falloc() should continue to insert the struct file in
the list.  That list is only used for userland tools like fstat and
fuser.  And those tools should handle open files that don't have a
file descriptor.

> Index: sys/kern/exec_script.c
> ===
> RCS file: /cvs/src/sys/kern/exec_script.c,v
> retrieving revision 1.46
> diff -u -p -r1.46 exec_script.c
> --- sys/kern/exec_script.c5 Jun 2018 09:29:05 -   1.46
> +++ sys/kern/exec_script.c14 Jun 2018 11:54:38 -
> @@ -170,17 +170,20 @@ check_shell:
>  #endif
>  
>   fdplock(p->p_fd);
> - error = falloc(p, 0, &fp, &epp->ep_fd);
> - fdpunlock(p->p_fd);
> - if (error)
> + error = falloc(p, &fp, &epp->ep_fd);
> + if (error) {
> + fdpunlock(p->p_fd);
>   goto fail;
> + }
>  
>   epp->ep_flags |= EXEC_HASFD;
>   fp->f_type = DTYPE_VNODE;
>   fp->f_ops = &vnops;
>   fp->f_data = (caddr_t) scriptvp;
>   fp->f_flag = FREAD;
> - FILE_SET_MATURE(fp, p);
> + fdinsert(p->p_fd, epp->ep_fd, 0, fp);
> + fdpunlock(p->p_fd);
> + FRELE(fp, p);
>   }
>  
>   /* set up the parameters for the recursive check_exec() call */
> Index: sys/kern/kern_descrip.c
> ===
> RCS file: /cvs/src/sys/kern/kern_descrip.c,v
> retrieving revision 1.164
> diff -u -p -r1.164 kern_descrip.c
> --- sys/kern/kern_descrip.c   5 Jun 2018 09:29:05 -   1.164
> +++ sys/kern/kern_descrip.c   14 Jun 2018 11:54:38 -
> @@ -73,6 +73,7 @@ int numfiles;   /* actual number of open
>  static __inline void fd_used(struct filedesc *, int);
>  static __inline void fd_unused(struct filedesc *, int);
>  static __inline int find_next_zero(u_int *, int, u_int);
> +static __inline int fd_inuse(struct filedesc *, int);
>  int finishdup(struct proc *, struct file *, int, int, register_t *, int);
>  int find_last_set(struct filedesc *, int);
>  int dodup3(struct proc *, int, int, int, register_t *);
> @@ -125,7 +126,6 @@ int
>  find_last_set(struct filedesc *fd, int last)
>  {
>   int off, i;
> - struct file **ofiles = fd->fd_ofiles;
>   u_int *bitmap = fd->fd_lomap;
>  
>   off = (last - 1) >> NDENTRYSHIFT;
> @@ -139,11 +139,22 @@ find_last_set(struct filedesc *fd, int l
>   if (i >= last)
>   i = last - 1;
>  
> - while (i > 0 && ofiles[i] == NULL)
> + while (i > 0 && !fd_inuse(fd, i))
>   i--;
>   return i;
>  }
>  
> +static __inline int
> +fd_inuse(struct filedesc *fdp, int fd)
> +{
> + u_int off = fd >> NDENTRYSHIFT;
> +
> + if (fdp->fd_lomap[off] & (1 << (fd & NDENTRYMASK)))
> + return 1;
> +
> + return 0;
> +}
> +
>  static __inline void
>  fd_used(struct filedesc *fdp, int fd)
>  {
> @@ -190,7 +201,7 @@ fd_iterfile(struct file *fp, struct proc
>   nfp = LIST_NEXT(fp, f_list);
>  
>   /* don't FREF when f_count == 0 to avoid race in fdrop() */
> - while (nfp != NULL && (nfp->f_count == 0 || !FILE_IS_USABLE(nfp)))
> + while (nfp != NULL && nfp->f_count == 0)
>   nfp = LIST_NEXT(nfp, f_list);
>   if (nfp != NULL)
>   FREF(nfp);
> @@ -209,9 +220,6 @@ fd_getfile(struct filedesc *fdp, int fd)
>   if ((u_int)fd >=

Re: ksh "clear-screen" editing command

2018-06-16 Thread Mark Kettenis
> Date: Sat, 16 Jun 2018 18:15:42 +0200
> From: Tomasz Rola 
> 
> On Sat, Jun 16, 2018 at 02:50:40PM +0200, Mark Kettenis wrote:
> [...]
> > 
> > To e honest, I find the whole idea of invoking an external program to
> > clear the screen insane.
> 
> Not necesarilly wanting to quarrel about this, but:
> 
> 1. What would you say to someone who wants to run an old sh script
> which employs exactly this method?
> 
> 2. What am I supposed to use instead when I want to clear the screen
> from the inside of newly written sh script, while (hopefully) staying
> compatible with other systems (some of them old and non-upgradeable)?
> 
> The cost of running external program that only knows one thing and
> knows it well is minimal, even more so on modern platforms. Additional
> benefit is having to change only this one program if such a need
> arises in a future.
> 
> Just my cent or two.

You're missing the point here.  Calling /usr/bin/clear to clear the
screen from one of your scripts is fone.  Doing so because you press a
certain key combination while at the shell prompt isn't.



Re: ksh "clear-screen" editing command

2018-06-17 Thread Mark Kettenis
> From: "Todd C. Miller" 
> Date: Sun, 17 Jun 2018 09:00:17 -0600
> 
> On Sat, 16 Jun 2018 16:16:57 -0600, "Todd C. Miller" wrote:
> 
> > On Sat, 16 Jun 2018 14:50:40 +0200, Mark Kettenis wrote:
> >
> > > To be honest, I find the whole idea of invoking an external program to
> > > clear the screen insane.
> >
> > Linking with curses doesn't increase the size a huge amount since
> > we just need to query terminfo.
> >
> > textdatabss dec hex
> > 529120  12584   57024   598728  922c8   /bin/ksh
> > 595671  21904   57024   674599  a4b27   ./obj/ksh
> 
> Slightly simpler, we can use the clear_screen macro instead of looking
> it up with tigetstr().
> 
> textdatabss dec hex
> 529120  12584   57024   598728  922c8   /bin/ksh
> 594844  21888   57024   673756  a47dc   ./obj/ksh

If folks indeed think that this is a must-have feature, this is
certainly a better approach.  I wonder though if the setupterm() call
should happen earlier when interactive mode is initialized?  Probably
best to link against libterminfo to indicate that we don't really want
full-blown curses.

The man page needs to be adjusted now that you no longer call clear(1).

Cheers,

Mark

> Index: Makefile
> ===
> RCS file: /cvs/src/bin/ksh/Makefile,v
> retrieving revision 1.38
> diff -u -p -u -r1.38 Makefile
> --- Makefile  6 Jan 2018 16:28:58 -   1.38
> +++ Makefile  16 Jun 2018 22:00:32 -
> @@ -1,6 +1,9 @@
>  #$OpenBSD: Makefile,v 1.38 2018/01/06 16:28:58 millert Exp $
>  
>  PROG=ksh
> +DPADD+=  ${LIBCURSES}
> +LDADD+=  -lcurses
> +
>  SRCS=alloc.c c_ksh.c c_sh.c c_test.c c_ulimit.c edit.c emacs.c 
> eval.c \
>   exec.c expr.c history.c io.c jobs.c lex.c mail.c main.c \
>   misc.c path.c shf.c syn.c table.c trap.c tree.c tty.c var.c \
> Index: edit.c
> ===
> RCS file: /cvs/src/bin/ksh/edit.c,v
> retrieving revision 1.65
> diff -u -p -u -r1.65 edit.c
> --- edit.c9 Apr 2018 17:53:36 -   1.65
> +++ edit.c16 Jun 2018 22:09:17 -
> @@ -138,10 +138,10 @@ x_flush(void)
>   shf_flush(shl_out);
>  }
>  
> -void
> +int
>  x_putc(int c)
>  {
> - shf_putc(c, shl_out);
> + return shf_putc(c, shl_out);
>  }
>  
>  void
> Index: edit.h
> ===
> RCS file: /cvs/src/bin/ksh/edit.h,v
> retrieving revision 1.11
> diff -u -p -u -r1.11 edit.h
> --- edit.h26 Jan 2016 17:39:31 -  1.11
> +++ edit.h16 Jun 2018 22:09:27 -
> @@ -37,7 +37,7 @@ extern X_chars edchars;
>  /* edit.c */
>  int  x_getc(void);
>  void x_flush(void);
> -void x_putc(int);
> +int  x_putc(int);
>  void x_puts(const char *);
>  bool x_mode(bool);
>  int  promptlen(const char *, const char **);
> Index: emacs.c
> ===
> RCS file: /cvs/src/bin/ksh/emacs.c,v
> retrieving revision 1.84
> diff -u -p -u -r1.84 emacs.c
> --- emacs.c   16 Jan 2018 17:17:18 -  1.84
> +++ emacs.c   17 Jun 2018 13:58:36 -
> @@ -21,6 +21,10 @@
>  #include 
>  #include 
>  #include 
> +#ifndef SMALL
> +# include 
> +# include 
> +#endif
>  
>  #include "sh.h"
>  #include "edit.h"
> @@ -28,6 +32,7 @@
>  static   Areaaedit;
>  #define  AEDIT   &aedit  /* area for kill ring and macro defns */
>  
> +#undef CTRL
>  #define  CTRL(x) ((x) == '?' ? 0x7F : (x) & 0x1F)/* 
> ASCII */
>  #define  UNCTRL(x)   ((x) == 0x7F ? '?' : (x) | 0x40)/* 
> ASCII */
>  
> @@ -146,6 +151,7 @@ static intisu8cont(unsigned char);
>  /* proto's for keybindings */
>  static int   x_abort(int);
>  static int   x_beg_hist(int);
> +static int   x_clear_screen(int);
>  static int   x_comp_comm(int);
>  static int   x_comp_file(int);
>  static int   x_complete(int);
> @@ -202,6 +208,7 @@ static intx_debug_info(int);
>  static const struct x_ftab x_ftab[] = {
>   { x_abort,  "abort",0 },
>   { x_beg_hist,   "beginning-of-history", 0 },
> + { x_clear_screen,   "clear-screen", 0 },
>   { x_comp_comm,  "complete-command", 0 },
>   { x_comp_file,  "complete-file",0 },
>   { x_complete,   "complete", 0 },
&

Re: fdinsert(), take 3

2018-06-18 Thread Mark Kettenis
> Date: Mon, 18 Jun 2018 09:07:58 +0200
> From: Martin Pieuchot 
> 
> On 16/06/18(Sat) 19:28, Mark Kettenis wrote:
> > > Date: Thu, 14 Jun 2018 14:28:07 +0200
> > > From: Martin Pieuchot 
> > > 
> > > This version should fixes the previous issue where LARVAL files were
> > > incorrectly accounted in find_last_set() resulting in a panic() in
> > > fd_unused().
> > > 
> > > If you haven't read the previous explanations, the idea of this diff
> > > is to publish file descriptors only when they are completely setup.
> > > This will allow us to serialize access to file descriptors in a mp-safe
> > > way, which is the last requirement for unlock most of the socket-related
> > > syscalls.
> > > 
> > > The important point of this diff is that we don't store on the descriptor
> > > itself the fact that it isn't ready yet (LARVAL).  Otherwise we have a
> > > chicken & egg problem for reference counting.  As pointed by Mathieu
> > > Masson other BSDs do that by using a new structure for open files.  We
> > > might want to do that later when we'll turn these functions mp-safe :)
> > > For now, using the existing bitmask is good enough.
> > > 
> > > Here are previous explanations:
> > >   https://marc.info/?l=openbsd-tech&m=152579630904328&w=2
> > >   https://marc.info/?l=openbsd-tech&m=152750590114899&w=2
> > > 
> > > Please test & report as usual.
> > > 
> > > Ok?
> > 
> > Sorry, but no, I don't think this diff is ok.  Your new code inserts
> > the struct file into the linked list of all open files on fdinsert().
> 
> Yes, that's the goal of my diff.  No descriptor should be reachable by
> another thread before fdinsert() has been called.  Since the linked list
> offers such possibility it should be delayed.

But the linked list doesn't point at file descriptors.  It points at
open files.  Those are different concepts.  An open file can have any
number of file descriptors associated with it.  And that number can
even be zero.  This happens when you pass a file descrptor to another
proecess using sendmsg(2) and close it immediately.  Until the other
side calls recmsg(2) there is no file descriptor for the file, but it
is still open.

The sole purpose of the linked list is to implement the
KERN_FILE_BYFILE sysctl.  And all that sysctl does is copy the
contents of the struct file to userland.  The linked list should not
be used for any other purpose.  Userland has to deal with the fact
that the contents of that struct file are stale already.

I guess this point is a bit academic.  The current file descriptor
APIs are heavily geared towards opening a file and creating a file
descriptor in one operation.  I think that is somewhat of a design
mistake.  And it is not your design mistake.  But it seems to be
influencing your locking design and I'm not sure the direction you're
heading is the right one.

The diff you committed is mostly fine.  I'll comment on the next diff
to point out some alternatives instead.

> > However, there is code that bails out and calls closef() before that
> > fdinsert() happens.  For exacmple in kern_exec.c:sys_execve() and in
> > sys_pipe.c:dopipe() (if the 2nd falloc() call fails).
> 
> There's no problem with that.

Ah, you explicitly check the FIF_INSERTED flag.  So you skip te
LIST_REMOVE() if the struct file is not on the list.

> > I really think falloc() should continue to insert the struct file in
> > the list.  That list is only used for userland tools like fstat and
> > fuser.  And those tools should handle open files that don't have a
> > file descriptor.
> 
> Such files almost never exist Mark, only in accept(2).  All other sycalls
> block on the fdplock().  I'm not going to change the sysctl interface
> to make it MP-safe and fix all the related bug in all subsystems ;)
> 
> However I'd glad if you could come up with a way to show such files in
> a MP-safe way after I've committed my diff. You can even try visa@'s
> diff:  https://marc.info/?l=openbsd-tech&m=152794586504816&w=2
> 



Re: Unlock sendit-based syscalls

2018-06-18 Thread Mark Kettenis
> Date: Mon, 18 Jun 2018 11:24:00 +0200
> From: Martin Pieuchot 
> 
> Diff below is the last of the serie to remove the KERNEL_LOCK() from
> sendto(2) and sendmsg(2) for sockets protected by the NET_LOCK().
> 
> As explained previously [0] this diff uses a simple non-intrusive
> approached based on a single mutex.  I'd like to get this in before
> doing any refactoring of this layer to get real test coverages.
> 
> [0] https://marc.info/?l=openbsd-tech&m=152699644924165&w=2
> 
> Tests?  Comments?  Oks?

At first sight this diff seems to mess up the locking quite a bit.
I'm sure that is intentional, but still I'm not sure this is the right
direction.  In my mind we should at some point in the future be able
to use atomic operations to manage the reference count on struct file
(f_count).  Using atomic operations has the huge benefit of not having
lock ordering problems!  But it looks as if this diff gets us further
away from that goal.

You'll still need a lock for the global list of course.  It is easy to
protect insertions and removals.  The real problem is indeed
fd_iterfile().  There you want to take a reference but that isn't
really safe since you don't necessarily hold one already.  That's why
we have that f_count == 0 check there.  And as long as you're holding
the lock that protects the list you know the struct file is not going
to disappear.  So if f_count > 0 you can safely take a reference.  But
calling FREF while holding a mutex is problematic because of
vfs_stall_barrier().  You're correct that vfs_stall_barrier() isn't
required here.  All you need to do is atomically increase the
reference count.  So this one is indeed a bit special.  And using a
mutex to protect the reference counts could still work here.

What I don't understand is why you also protect the manipulation of
the file descriptor tables with the mutex in some places.  Those
tables are already protected by a lock!

All in all, I think that using atomic operations for the reference
count would really help.

> Index: kern/kern_descrip.c
> ===
> RCS file: /cvs/src/sys/kern/kern_descrip.c,v
> retrieving revision 1.166
> diff -u -p -r1.166 kern_descrip.c
> --- kern/kern_descrip.c   18 Jun 2018 09:15:05 -  1.166
> +++ kern/kern_descrip.c   18 Jun 2018 09:16:20 -
> @@ -66,7 +66,11 @@
>  
>  /*
>   * Descriptor management.
> + *
> + * We need to block interrupts as long as `fhdlk' is being taken
> + * with and without the KERNEL_LOCK().
>   */
> +struct mutex fhdlk = MUTEX_INITIALIZER(IPL_MPFLOOR);
>  struct filelist filehead;/* head of list of open files */
>  int numfiles;/* actual number of open files */
>  
> @@ -195,16 +199,18 @@ fd_iterfile(struct file *fp, struct proc
>  {
>   struct file *nfp;
>  
> + mtx_enter(&fhdlk);
>   if (fp == NULL)
>   nfp = LIST_FIRST(&filehead);
>   else
>   nfp = LIST_NEXT(fp, f_list);
>  
> - /* don't FREF when f_count == 0 to avoid race in fdrop() */
> + /* don't refcount when f_count == 0 to avoid race in fdrop() */
>   while (nfp != NULL && nfp->f_count == 0)
>   nfp = LIST_NEXT(nfp, f_list);
>   if (nfp != NULL)
> - FREF(nfp);
> + nfp->f_count++;
> + mtx_leave(&fhdlk);
>  
>   if (fp != NULL)
>   FRELE(fp, p);
> @@ -217,10 +223,17 @@ fd_getfile(struct filedesc *fdp, int fd)
>  {
>   struct file *fp;
>  
> - if ((u_int)fd >= fdp->fd_nfiles || (fp = fdp->fd_ofiles[fd]) == NULL)
> + vfs_stall_barrier();
> +
> + if ((u_int)fd >= fdp->fd_nfiles)
>   return (NULL);
>  
> - FREF(fp);
> + mtx_enter(&fhdlk);
> + fp = fdp->fd_ofiles[fd];
> + if (fp != NULL)
> + fp->f_count++;
> + mtx_leave(&fhdlk);
> +
>   return (fp);
>  }
>  
> @@ -671,6 +684,8 @@ fdinsert(struct filedesc *fdp, int fd, i
>   struct file *fq;
>  
>   fdpassertlocked(fdp);
> +
> + mtx_enter(&fhdlk);
>   if ((fq = fdp->fd_ofiles[0]) != NULL) {
>   LIST_INSERT_AFTER(fq, fp, f_list);
>   } else {
> @@ -680,6 +695,7 @@ fdinsert(struct filedesc *fdp, int fd, i
>   fdp->fd_ofiles[fd] = fp;
>   fdp->fd_ofileflags[fd] |= (flags & UF_EXCLOSE);
>   fp->f_iflags |= FIF_INSERTED;
> + mtx_leave(&fhdlk);
>  }
>  
>  void
> @@ -978,7 +994,11 @@ restart:
>   crhold(fp->f_cred);
>   *resultfp = fp;
>   *resultfd = i;
> - FREF(fp);
> +
> + mtx_enter(&fhdlk);
> + fp->f_count++;
> + mtx_leave(&fhdlk);
> +
>   return (0);
>  }
>  
> @@ -1069,6 +1089,7 @@ fdcopy(struct process *pr)
>   newfdp->fd_flags = fdp->fd_flags;
>   newfdp->fd_cmask = fdp->fd_cmask;
>  
> + mtx_enter(&fhdlk);
>   for (i = 0; i <= fdp->fd_lastfile; i++) {
>   struct file *fp = fdp->fd_ofiles[i];
>  
> @@ -1085,12 +1106,13 @@ fdcopy(struct process *pr)
>   fp->f_type == DTYPE_KQUE

Re: Unlock sendit-based syscalls

2018-06-19 Thread Mark Kettenis
> Date: Tue, 19 Jun 2018 10:54:21 +0200
> From: Martin Pieuchot 
> 
> On 18/06/18(Mon) 18:18, Mark Kettenis wrote:
> > > Date: Mon, 18 Jun 2018 11:24:00 +0200
> > > From: Martin Pieuchot 
> > > 
> > > Diff below is the last of the serie to remove the KERNEL_LOCK() from
> > > sendto(2) and sendmsg(2) for sockets protected by the NET_LOCK().
> > > 
> > > As explained previously [0] this diff uses a simple non-intrusive
> > > approached based on a single mutex.  I'd like to get this in before
> > > doing any refactoring of this layer to get real test coverages.
> > > 
> > > [0] https://marc.info/?l=openbsd-tech&m=152699644924165&w=2
> > > 
> > > Tests?  Comments?  Oks?
> > 
> > At first sight this diff seems to mess up the locking quite a bit.
> > I'm sure that is intentional, but still I'm not sure this is the right
> > direction.  In my mind we should at some point in the future be able
> > to use atomic operations to manage the reference count on struct file
> > (f_count).  Using atomic operations has the huge benefit of not having
> > lock ordering problems!  But it looks as if this diff gets us further
> > away from that goal.
> > 
> > You'll still need a lock for the global list of course.  It is easy to
> > protect insertions and removals.  The real problem is indeed
> > fd_iterfile().  There you want to take a reference but that isn't
> > really safe since you don't necessarily hold one already.  That's why
> > we have that f_count == 0 check there.  And as long as you're holding
> > the lock that protects the list you know the struct file is not going
> > to disappear.  So if f_count > 0 you can safely take a reference.  But
> > calling FREF while holding a mutex is problematic because of
> > vfs_stall_barrier().  You're correct that vfs_stall_barrier() isn't
> > required here.  All you need to do is atomically increase the
> > reference count.  So this one is indeed a bit special.  And using a
> > mutex to protect the reference counts could still work here.
> 
> I agree with your analyse.  My plan was a bit different.  I wanted to
> properly track references of elements on the list.  That means that
> kern_sysctl() could now be freeing a struct file, which shouldn't be
> a problem.
> 
> > What I don't understand is why you also protect the manipulation of
> > the file descriptor tables with the mutex in some places.  Those
> > tables are already protected by a lock!
> 
> That's the most important part of this diff.  My goal is to ensure
> that a descriptor returned by fd_getfile() is and will stay valid
> during the whole execution of an unlocked syscall.

The file descriptor doesn't have to stay valid (i.e. visible).  Only
the struct file associated with it.  But I guess that is what you mean.

> To avoid races with another thread that might be clearing our pointer
> in `fd_ofiles', we need more than atomic operations.  For that we need
> to serialize the threads.  The most simple way to do so is with a mutex
> on a different data structure.  Either global, like in my diff, or as
> visa@ suggested in the corresponding `fdp'.

Right.  Another case of trying to take a reference without holding one
already.  The trick here is to use the fact that as long as there is a
file descriptor allocated for this open file the reference count is at
least 1.  So in that case taking a reference is safe.  Your global
mutex does indeed do the trick.  But why aren't you using the file
descriptor table rwlock for this purpose?  Is that because there is a
lock ordering problem between the kernel lock and that rwlock?

> > All in all, I think that using atomic operations for the reference
> > count would really help.
> 
> I agree, I just wanted to keep the logic easy in a first step.  It
> shouldn't be hard to split the mutex I'm using. 

The thing I'm a little bit worried about is that by inlining part of
FREF() in various places it will be harder to eventually use atomic
reference counts.  On the other hand those cases serve as a marker for
the spots where the reference counting needs a little bit more
attention.

I'd like to have an answer to my question about the rwlock.  But if
the answer is indeed that there is a rwlock, I think this diff is good
to go.

> > > Index: kern/kern_descrip.c
> > > ===
> > > RCS file: /cvs/src/sys/kern/kern_descrip.c,v
> > > retrieving revision 1.166
> > > diff -u -p -r1.166 kern_descrip.c
> > > --- kern/kern_descrip.c   

Re: Prevent races w/ f_data

2018-06-19 Thread Mark Kettenis
> Date: Tue, 19 Jun 2018 12:51:35 +0200
> From: Martin Pieuchot 
> 
> There's one place in our kernel where `f_data' is overwritten while the
> descriptor sits in multiple shared data structures.  It is in diskmap.
> 
> We want to avoid this situation to be able to treat f_data as immutable.
> 
> So the diff below remove `fp' from the shared data structures before it
> gets modified.  It is not a complete solution to the reference grabbing
> problem of vnode.  There's still a window where a race is possible
> between the moment where we release the mutex and increase the vnode's
> reference.  The KERNEL_LOCK() is what protects us for now.  However this
> problem is the next one to solve to be able to unlock syscalls messing
> with vnodes.
> 
> Still this diff is a step towards that.
> 
> Note that this change only apply to vnodes, so it doesn't matter for
> socket-related syscalls.
> 
> Ok?

I think this is the wrong approach.  Instead of modifying the struct
file, this code should create a new struct file.  Then replace the
pointer in the file descriptor table with that new file and then drop
the reference to the old struct file.  That way f_data *is* immutable.

> Index: dev/diskmap.c
> ===
> RCS file: /cvs/src/sys/dev/diskmap.c,v
> retrieving revision 1.20
> diff -u -p -r1.20 diskmap.c
> --- dev/diskmap.c 9 May 2018 08:42:02 -   1.20
> +++ dev/diskmap.c 19 Jun 2018 10:38:37 -
> @@ -59,7 +59,7 @@ diskmapioctl(dev_t dev, u_long cmd, cadd
>   struct filedesc *fdp = p->p_fd;
>   struct file *fp = NULL;
>   struct vnode *vp = NULL, *ovp;
> - char *devname;
> + char *devname, flags;
>   int fd, error = EINVAL;
>  
>   if (cmd != DIOCMAP)
> @@ -106,6 +106,15 @@ diskmapioctl(dev_t dev, u_long cmd, cadd
>   vput(ovp);
>   }
>  
> + /* Remove the file while we're modifying it to prevent races. */
> + flags = fdp->fd_ofileflags[fd];
> + mtx_enter(&fhdlk);
> + fdp->fd_ofiles[fd] = NULL;
> + fdp->fd_ofileflags[fd] = 0;
> + if (fp->f_iflags & FIF_INSERTED)
> + LIST_REMOVE(fp, f_list);
> + mtx_leave(&fhdlk);
> +
>   fp->f_data = (caddr_t)vp;
>   fp->f_offset = 0;
>   mtx_enter(&fp->f_mtx);
> @@ -115,6 +124,9 @@ diskmapioctl(dev_t dev, u_long cmd, cadd
>   fp->f_rbytes = 0;
>   fp->f_wbytes = 0;
>   mtx_leave(&fp->f_mtx);
> +
> + /* Insert it back where it was. */
> + fdinsert(fdp, fd, flags, fp);
>  
>   VOP_UNLOCK(vp);
>  
> 
> 



Re: Unlock sendit-based syscalls

2018-06-19 Thread Mark Kettenis
> Date: Tue, 19 Jun 2018 15:38:01 +0200
> From: Martin Pieuchot 
> 
> On 19/06/18(Tue) 14:55, Mark Kettenis wrote:
> > > To avoid races with another thread that might be clearing our pointer
> > > in `fd_ofiles', we need more than atomic operations.  For that we need
> > > to serialize the threads.  The most simple way to do so is with a mutex
> > > on a different data structure.  Either global, like in my diff, or as
> > > visa@ suggested in the corresponding `fdp'.
> > 
> > Right.  Another case of trying to take a reference without holding one
> > already.  The trick here is to use the fact that as long as there is a
> > file descriptor allocated for this open file the reference count is at
> > least 1.  So in that case taking a reference is safe.  Your global
> > mutex does indeed do the trick.  But why aren't you using the file
> > descriptor table rwlock for this purpose?  Is that because there is a
> > lock ordering problem between the kernel lock and that rwlock?
> 
> I have two reasons.  First I don't want to introduce new sleeping points,
> secondly I want this mutex to disappear.  IMHO extending the scope of a
> lock is going in the wrong direction because then we'll want to split it.
> That's why I'm happy that our discussion made visa@ look at improving this.

I wouldn't call this extending the scope of the lock.  But yes, it
might cause unnecessary sleeps if a write lock is held for the purpose
of opening a file.  The mutex that visa@ proposes trades that in for
potential contion in the multiple-readers case.



Re: Prevent races w/ f_data

2018-06-19 Thread Mark Kettenis
> Date: Tue, 19 Jun 2018 15:45:48 +0200
> From: Martin Pieuchot 
> 
> On 19/06/18(Tue) 15:08, Mark Kettenis wrote:
> > > Date: Tue, 19 Jun 2018 12:51:35 +0200
> > > From: Martin Pieuchot 
> > > 
> > > There's one place in our kernel where `f_data' is overwritten while the
> > > descriptor sits in multiple shared data structures.  It is in diskmap.
> > > 
> > > We want to avoid this situation to be able to treat f_data as immutable.
> > > 
> > > So the diff below remove `fp' from the shared data structures before it
> > > gets modified.  It is not a complete solution to the reference grabbing
> > > problem of vnode.  There's still a window where a race is possible
> > > between the moment where we release the mutex and increase the vnode's
> > > reference.  The KERNEL_LOCK() is what protects us for now.  However this
> > > problem is the next one to solve to be able to unlock syscalls messing
> > > with vnodes.
> > > 
> > > Still this diff is a step towards that.
> > > 
> > > Note that this change only apply to vnodes, so it doesn't matter for
> > > socket-related syscalls.
> > > 
> > > Ok?
> > 
> > I think this is the wrong approach.  Instead of modifying the struct
> > file, this code should create a new struct file.  Then replace the
> > pointer in the file descriptor table with that new file and then drop
> > the reference to the old struct file.  That way f_data *is* immutable.
> 
> I tried that first... well it didn't work for me.
> 
> The problem is that once you swapped `fp' you still need to free the old
> one.  But you don't want to close the associated file, so you end up
> NULLing `f_data' before calling closef()...

You simply call FRELE() on the old struct file.  That should properly
close the file once the last reference goes.  Obviously you'd remove
the code that closes the original vnode from diskmapioctl().  I don't
see how closef() would be called in that scenario, since you're not
releasing the file descriptor.

> On top of that this approach introduces a new error condition if we
> reach `maxfiles', yes this is a degenerated case but I'd prefer not
> have to deal with it.

True.  And it changes the semantics of the DIOCMAP ioctl.  Currently,
if you call DIOCMAP on a dup'ed file descriptor it would change the
open file associated with all of them.  With my suggestion, it will
only change the open file for the file descriptor you're operating on.
The other file descriptor would continue to refer to the original open
file (typically the diskmap device, but not necessarily).  I'd argue
that is actually how this ioctl should behave.

In fact the current behaviour is a bit of a security risk.  I could
open a file, pass the descriptor to another process and then call
DIOCMAP and suddenly the other process has a ilfe descriptor that
refers to a disk device instead of a normal file.

> The approach below returns `fp' into the "larval" or "reserved" state,
> change it, then insert it again.
> 
> > 
> > > Index: dev/diskmap.c
> > > ===
> > > RCS file: /cvs/src/sys/dev/diskmap.c,v
> > > retrieving revision 1.20
> > > diff -u -p -r1.20 diskmap.c
> > > --- dev/diskmap.c 9 May 2018 08:42:02 -   1.20
> > > +++ dev/diskmap.c 19 Jun 2018 10:38:37 -
> > > @@ -59,7 +59,7 @@ diskmapioctl(dev_t dev, u_long cmd, cadd
> > >   struct filedesc *fdp = p->p_fd;
> > >   struct file *fp = NULL;
> > >   struct vnode *vp = NULL, *ovp;
> > > - char *devname;
> > > + char *devname, flags;
> > >   int fd, error = EINVAL;
> > >  
> > >   if (cmd != DIOCMAP)
> > > @@ -106,6 +106,15 @@ diskmapioctl(dev_t dev, u_long cmd, cadd
> > >   vput(ovp);
> > >   }
> > >  
> > > + /* Remove the file while we're modifying it to prevent races. */
> > > + flags = fdp->fd_ofileflags[fd];
> > > + mtx_enter(&fhdlk);
> > > + fdp->fd_ofiles[fd] = NULL;
> > > + fdp->fd_ofileflags[fd] = 0;
> > > + if (fp->f_iflags & FIF_INSERTED)
> > > + LIST_REMOVE(fp, f_list);
> > > + mtx_leave(&fhdlk);
> > > +
> > >   fp->f_data = (caddr_t)vp;
> > >   fp->f_offset = 0;
> > >   mtx_enter(&fp->f_mtx);
> > > @@ -115,6 +124,9 @@ diskmapioctl(dev_t dev, u_long cmd, cadd
> > >   fp->f_rbytes = 0;
> > >   fp->f_wbytes = 0;
> > >   mtx_leave(&fp->f_mtx);
> > > +
> > > + /* Insert it back where it was. */
> > > + fdinsert(fdp, fd, flags, fp);
> > >  
> > >   VOP_UNLOCK(vp);
> > >  
> > > 
> > > 
> 
> 



Do you have an AMD Ryzen or Epyc CPU?

2018-06-19 Thread Mark Kettenis
Looking for people that can run a kernel with the patch below and mail
me the resulting dmesg.

Thanks,

Mark


Index: arch/amd64/amd64/identcpu.c
===
RCS file: /cvs/src/sys/arch/amd64/amd64/identcpu.c,v
retrieving revision 1.96
diff -u -p -r1.96 identcpu.c
--- arch/amd64/amd64/identcpu.c 7 Jun 2018 04:07:28 -   1.96
+++ arch/amd64/amd64/identcpu.c 19 Jun 2018 20:27:24 -
@@ -803,6 +803,11 @@ cpu_topology(struct cpu_info *ci)
/* Pkg id is the upper remaining bits */
ci->ci_pkg_id = apicid & ~core_mask;
ci->ci_pkg_id >>= core_bits;
+   if (ci->ci_pnfeatset >= 0x801e) {
+   CPUID(0x801e, eax, ebx, ecx, edx);
+   printf("cpu%d: eax 0x%08x ebx 0x%08x ecx 0x%08x\n",
+   ci->ci_cpuid, eax, ebx, ecx);
+   }
} else if (strcmp(cpu_vendor, "GenuineIntel") == 0) {
/* We only support leaf 1/4 detection */
if (cpuid_level < 4)



Re: Do you have an AMD Ryzen or Epyc CPU?

2018-06-20 Thread Mark Kettenis
> Date: Wed, 20 Jun 2018 20:29:51 +1000
> From: Jonathan Matthew 
> 
> On Wed, Jun 20, 2018 at 10:38:41AM +0100, Stuart Henderson wrote:
> > On 2018/06/20 05:53, Leo Unglaub wrote:
> > > Hi,
> > > I applied your code on my AMD Ryzen 7 1700X. Below is the dmesg. I hope 
> > > this
> > > helps, if you have any other AMD Ryzen related stuff that needs testing
> > > please let me know.
> > 
> > So there's no convenient "smt id" returned..
> > 
> > 
> > The reacharound is a bit ugly, but would something like this do the trick?
> > I don't have a suitable AMD to test, but have tested the mechanism on an
> > i7 with HT and it does what's expected.
> 
> Here's what this does on a single socket epyc 7551p:
> 
> cpu0: smt 0, core 0, package 0
> cpu1: smt 0, core 8, package 1
> cpu2: smt 0, core 16, package 2
> cpu3: smt 0, core 24, package 3
> cpu4: smt 0, core 4, package 0
> cpu5: smt 0, core 12, package 1
> cpu6: smt 0, core 20, package 2
> cpu7: smt 0, core 28, package 3
> cpu8: smt 0, core 1, package 0
> cpu9: smt 0, core 9, package 1
> cpu10: smt 0, core 17, package 2
> cpu11: smt 0, core 25, package 3
> cpu12: smt 0, core 5, package 0
> cpu13: smt 0, core 13, package 1
> cpu14: smt 0, core 21, package 2
> cpu15: smt 0, core 29, package 3
> cpu16: smt 0, core 2, package 0
> cpu17: smt 0, core 10, package 1
> cpu18: smt 0, core 18, package 2
> cpu19: smt 0, core 26, package 3
> cpu20: smt 0, core 6, package 0
> cpu21: smt 0, core 14, package 1
> cpu22: smt 0, core 22, package 2
> cpu23: smt 0, core 30, package 3
> cpu24: smt 0, core 3, package 0
> cpu25: smt 0, core 11, package 1
> cpu26: smt 0, core 19, package 2
> cpu27: smt 0, core 27, package 3
> cpu28: smt 0, core 7, package 0
> cpu29: smt 0, core 15, package 1
> cpu30: smt 0, core 23, package 2
> cpu31: smt 0, core 31, package 3
> cpu32: smt 1, core 0, package 0
> cpu33: smt 1, core 8, package 1
> cpu34: smt 1, core 16, package 2
> cpu35: smt 1, core 24, package 3
> cpu36: smt 1, core 4, package 0
> cpu37: smt 1, core 12, package 1
> cpu38: smt 1, core 20, package 2
> cpu39: smt 1, core 28, package 3
> cpu40: smt 1, core 1, package 0
> cpu41: smt 1, core 9, package 1
> cpu42: smt 1, core 17, package 2
> cpu43: smt 1, core 25, package 3
> cpu44: smt 1, core 5, package 0
> cpu45: smt 1, core 13, package 1
> cpu46: smt 1, core 21, package 2
> cpu47: smt 1, core 29, package 3
> cpu48: smt 1, core 2, package 0
> cpu49: smt 1, core 10, package 1
> cpu50: smt 1, core 18, package 2
> cpu51: smt 1, core 26, package 3
> cpu52: smt 1, core 6, package 0
> cpu53: smt 1, core 14, package 1
> cpu54: smt 1, core 22, package 2
> cpu55: smt 1, core 30, package 3
> cpu56: smt 1, core 3, package 0
> cpu57: smt 1, core 11, package 1
> cpu58: smt 1, core 19, package 2
> cpu59: smt 1, core 27, package 3
> cpu60: smt 1, core 7, package 0
> cpu61: smt 1, core 15, package 1
> cpu62: smt 1, core 23, package 2
> cpu63: smt 1, core 31, package 3
> 
> It's probably reasonable to think of nodes as being like separate
> pacakges.  I'm not sure what happens in two socket systems though.

According to the documentation, a node corresponds to a die and there
are 4 dies in a package.  So package is a bit of a misnomer here, but
since each die has its own memory controller you could argue that
treating dies as separate packages is a reasonable description of the
topology.  Although dies in a single package do seem to be coupled
somewhat tighter as dies within a package are directly connected
whereas dies in different packages may not be.

My expectation is that on a dual socket machine the nodes in the 2nd
socket will be numbered 4-7.

> If I turn SMT off, I get this, which doesn't quite look right:
> 
> cpu0: smt 0, core 0, package 0
> cpu1: smt 0, core 16, package 1
> cpu2: smt 0, core 32, package 2
> cpu3: smt 0, core 48, package 3
> cpu4: smt 0, core 8, package 0
> cpu5: smt 0, core 24, package 1
> cpu6: smt 0, core 40, package 2
> cpu7: smt 0, core 56, package 3
> cpu8: smt 0, core 1, package 0
> cpu9: smt 0, core 17, package 1
> cpu10: smt 0, core 33, package 2
> cpu11: smt 0, core 49, package 3
> cpu12: smt 0, core 9, package 0
> cpu13: smt 0, core 25, package 1
> cpu14: smt 0, core 41, package 2
> cpu15: smt 0, core 57, package 3
> cpu16: smt 0, core 2, package 0
> cpu17: smt 0, core 18, package 1
> cpu18: smt 0, core 34, package 2
> cpu19: smt 0, core 50, package 3
> cpu20: smt 0, core 10, package 0
> cpu21: smt 0, core 26, package 1
> cpu22: smt 0, core 42, package 2
> cpu23: smt 0, core 58, package 3
> cpu24: smt 0, core 3, package 0
> cpu25: smt 0, core 19, package 1
> cpu26: smt 0, core 35, package 2
> cpu27: smt 0, core 51, package 3
> cpu28: smt 0, core 11, package 0
> cpu29: smt 0, core 27, package 1
> cpu30: smt 0, core 43, package 2
> cpu31: smt 0, core 59, package 3

Well, it doesn't look wrong to me.  What's odd is that it seems the
cores got renumbered.  Cores 4-7, 12-15, etc. are no longer there.
But there now are cores with numbers in the 32-63 range.  As long as
we tre

Re: hw.smt / hw.ncpu / _SC_NPROCESSORS_ONLN

2018-06-20 Thread Mark Kettenis
> Date: Wed, 20 Jun 2018 13:05:05 +0100
> From: Stuart Henderson 
> 
> - Forwarded message from Mark Kettenis  -
> 
> From: Mark Kettenis 
> Date: Tue, 19 Jun 2018 13:29:52 -0600 (MDT)
> To: source-chan...@openbsd.org
> Subject: CVS: cvs.openbsd.org: src
> 
> CVSROOT:  /cvs
> Module name:  src
> Changes by:   kette...@cvs.openbsd.org2018/06/19 13:29:52
> 
> Modified files:
>   sys/arch/amd64/amd64: cpu.c 
>   sys/arch/amd64/include: cpu.h 
>   sys/kern   : kern_sched.c kern_sysctl.c 
>   sys/sys: sched.h sysctl.h 
> 
> Log message:
> SMT (Simultanious Multi Threading) implementations typically share
> TLBs and L1 caches between threads.  This can make cache timing
> attacks a lot easier and we strongly suspect that this will make
> several spectre-class bugs exploitable.  Especially on Intel's SMT
> implementation which is better known as Hypter-threading.  We really
> should not run different security domains on different processor
> threads of the same core.  Unfortunately changing our scheduler to
> take this into account is far from trivial.  Since many modern
> machines no longer provide the ability to disable Hyper-threading in
> the BIOS setup, provide a way to disable the use of additional
> processor threads in our scheduler.  And since we suspect there are
> serious risks, we disable them by default.  This can be controlled
> through a new hw.smt sysctl.  For now this only works on Intel CPUs
> when running OpenBSD/amd64.  But we're planning to extend this feature
> to CPUs from other vendors and other hardware architectures.
> 
> Note that SMT doesn't necessarily have a posive effect on performance;
> it highly depends on the workload.  In all likelyhood it will actually
> slow down most workloads if you have a CPU with more than two cores.
> 
> ok deraadt@
> 
> 
> - End forwarded message -
> 
> Some programs use hw.ncpu / sysconf(_SC_NPROCESSORS_ONLN) to determine
> how many threads/processes to run. (To pick an example from OpenBSD
> itself, dpb uses hw.ncpu), should we be adjusting that somehow?

sysconf(_SC_NPROCESSORS_ONLN) should probably exclude the offlined HT
threads.  But changing hw.ncpu is difficult as we have code that uses
that to enumerate the CPUs.  And on some machines cpu0 and cpu1 are
the threads of core 0 and cpu2 and cpu3 are the threads on core 1.  So
if hw.ncpu was set to 2, top(1) for example would only show CPU0 and
CPU1 with CPU1 being 100% idle.



Fix armv7 setjmp implementation

2018-06-20 Thread Mark Kettenis
The diff below fixes the setjmp implementation on armv7 to save and
restore the required floating-point registers.  The existing (but
disabled) code was written for the old FPA FPU.  The new VFP FPU
requires us to save a bit more stuff.  Fortunately the setjmp buffer
was already big enough so we just have to change te layout a bit and
don't have to have a full flag day.  Code that does peek or poke at
the contents of a setjmp buffer will have to be recompiled.  But such
code deserves to break.

Unfortunately this doesn't fix the /bin/sh crashes that now occur
regularly on armv7 :(.

ok?


Index: sys/arch/arm/include/setjmp.h
===
RCS file: /cvs/src/sys/arch/arm/include/setjmp.h,v
retrieving revision 1.4
diff -u -p -r1.4 setjmp.h
--- sys/arch/arm/include/setjmp.h   7 Aug 2016 02:02:57 -   1.4
+++ sys/arch/arm/include/setjmp.h   20 Jun 2018 16:00:13 -
@@ -11,26 +11,23 @@
  * Description of the setjmp buffer
  *
  * word  0 magic number(dependant on creator)
- *   1 -  3f4  fp register 4
- *  4 -  6 f5  fp register 5
- *  7 -  9 f6  fp register 6
- * 10 - 12 f7  fp register 7
- * 13  fpsrfp status register
- * 14  r13 register 13 (sp) XOR cookie0
- * 15  r14 register 14 (lr) XOR cookie1
- * 16  r4  register 4
- * 17  r5  register 5
- * 18  r6  register 6
- * 19  r7  register 7
- * 20  r8  register 8
- * 21  r9  register 9
- * 22  r10 register 10 (sl)
- * 23  r11 register 11 (fp)
- * 24  unused  unused
- * 25  signal mask (dependant on magic)
- * 26  (con't)
- * 27  (con't)
- * 28  (con't)
+ *   1 fpscr   fpscr
+ *   2 - 17d8 - d15vfp registers
+ * 18  r13 register 13 (sp) XOR cookie0
+ * 19  r14 register 14 (lr) XOR cookie1
+ * 20  r4  register 4
+ * 21  r5  register 5
+ * 22  r6  register 6
+ * 23  r7  register 7
+ * 24  r8  register 8
+ * 25  r9  register 9
+ * 26  r10 register 10 (sl)
+ * 27  r11 register 11 (fp)
+ * 28  unused  unused
+ * 29  signal mask (dependant on magic)
+ * 30  (con't)
+ * 31  (con't)
+ * 32  (con't)
  *
  * The magic number number identifies the jmp_buf and
  * how the buffer was created as well as providing
@@ -56,20 +53,15 @@
 /* Valid for all jmp_buf's */
 
 #define _JB_MAGIC   0
-#define _JB_REG_F4  1
-#define _JB_REG_F5  4
-#define _JB_REG_F6  7
-#define _JB_REG_F7 10
-#define _JB_REG_FPSR   13
-#define _JB_REG_R4 16
-#define _JB_REG_R5 17
-#define _JB_REG_R6 18
-#define _JB_REG_R7 19
-#define _JB_REG_R8 20
-#define _JB_REG_R9 21
-#define _JB_REG_R1022
-#define _JB_REG_R1123
+#define _JB_REG_R4 20
+#define _JB_REG_R5 21
+#define _JB_REG_R6 22
+#define _JB_REG_R7 23
+#define _JB_REG_R8 24
+#define _JB_REG_R9 25
+#define _JB_REG_R1026
+#define _JB_REG_R1127
 
 /* Only valid with the _JB_MAGIC_SETJMP magic */
 
-#define _JB_SIGMASK25
+#define _JB_SIGMASK29
Index: lib/libc/arch/arm/Makefile.inc
===
RCS file: /cvs/src/lib/libc/arch/arm/Makefile.inc,v
retrieving revision 1.8
diff -u -p -r1.8 Makefile.inc
--- lib/libc/arch/arm/Makefile.inc  28 Feb 2018 11:16:54 -  1.8
+++ lib/libc/arch/arm/Makefile.inc  20 Jun 2018 16:00:13 -
@@ -5,8 +5,6 @@
 
 CERROR=cerror.S
 
-CPPFLAGS += -DSOFTFLOAT
-
 # Override softfloat implementations of FP mode control functions
 .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/gen
 
Index: lib/libc/arch/arm/gen/_setjmp.S
===
RCS file: /cvs/src/lib/libc/arch/arm/gen/_setjmp.S,v
retrieving revision 1.5
diff -u -p -r1.5 _setjmp.S
--- lib/libc/arch/arm/gen/_setjmp.S 7 Aug 2016 02:02:57 -   1.5
+++ lib/libc/arch/arm/gen/_setjmp.S 20 Jun 2018 16:00:13 -
@@ -69,13 +69,13 @@ ENTRY(_setjmp)
eor r3, lr, r3  /* r3 = lr ^ __jmpxor[1] */
 
 #ifdef SOFTFLOAT
-   add r0, r0, #52
+   add r0, r0, #68
 #else
+   /* Store fpcsr */
+   vmrsr1, fpscr
+   str r1, [r0], #4
/* Store fp registers */
-   sfm f4, 4, [r0], #48
-   /* Store fpsr */

Re: Prevent races w/ f_data

2018-06-20 Thread Mark Kettenis
> Date: Wed, 20 Jun 2018 15:17:27 +0200
> From: Martin Pieuchot 

Joel, the diff below changes the semantics of the DIOCMAP ioctl a bit.
See the bit about DIOCMAP below.  I think this approach is better.
But maybe I'm missing someting...

Martin, I like fnew().  I can use that in the prime/DRI3 stuff as
well.  I'm still not convinced that inserting the struct file into the
list late is the right choice.  Yes, inserting it early (in fnew())
means that tools like fstat may see a struct file that is in an
inconsistent state.  But I'm not sure we can guarantee that anyway.
That would allow you to atomically replace the pointer in the file
descriptor table and be done.  Actually I think you could already
simplify the code and skip the "Zap old file" bit.  Just do a

   fdinsert(fdp, fd, 0, fp)

which will retain the flags.

Now if you really prefer to keep inserting late, could we change
fdinsert to only insert if FIF_INSERTED isn't set already?  That way
we can use it to insert the same open file into multiple file
descriptor tables.  I can include such a change in my prime/DRI3 diff.

Cheers.

Mark

> On 19/06/18(Tue) 16:40, Mark Kettenis wrote:
> > > Date: Tue, 19 Jun 2018 15:45:48 +0200
> > > From: Martin Pieuchot 
> > > On 19/06/18(Tue) 15:08, Mark Kettenis wrote:
> > > > [...]
> > > > I think this is the wrong approach.  Instead of modifying the struct
> > > > file, this code should create a new struct file.  Then replace the
> > > > pointer in the file descriptor table with that new file and then drop
> > > > the reference to the old struct file.  That way f_data *is* immutable.
> > > 
> > > I tried that first... well it didn't work for me.
> > > 
> > > The problem is that once you swapped `fp' you still need to free the old
> > > one.  But you don't want to close the associated file, so you end up
> > > NULLing `f_data' before calling closef()...
> > 
> > You simply call FRELE() on the old struct file.  That should properly
> > close the file once the last reference goes.  Obviously you'd remove
> > the code that closes the original vnode from diskmapioctl().  I don't
> > see how closef() would be called in that scenario, since you're not
> > releasing the file descriptor.
> 
> We need to close the original file, which means we have to decrement the
> refcounter twice.  So using closef() is the way to go, we're using the
> same semantic as in other file system syscalls.
> 
> Note however that the last reference on the original file will in most
> cases be released when returning from diskmapioctl().
> 
> > > On top of that this approach introduces a new error condition if we
> > > reach `maxfiles', yes this is a degenerated case but I'd prefer not
> > > have to deal with it.
> > 
> > True.  And it changes the semantics of the DIOCMAP ioctl.  Currently,
> > if you call DIOCMAP on a dup'ed file descriptor it would change the
> > open file associated with all of them.  With my suggestion, it will
> > only change the open file for the file descriptor you're operating on.
> > The other file descriptor would continue to refer to the original open
> > file (typically the diskmap device, but not necessarily).  I'd argue
> > that is actually how this ioctl should behave.
> > 
> > In fact the current behaviour is a bit of a security risk.  I could
> > open a file, pass the descriptor to another process and then call
> > DIOCMAP and suddenly the other process has a ilfe descriptor that
> > refers to a disk device instead of a normal file.
> 
> Diff below does that.  It also moves the fdplock() after vn_open(9)
> to not interleave it with the inode lock nor hold it while we recurse
> it other subsystems.
> 
> Index: dev/diskmap.c
> ===
> RCS file: /cvs/src/sys/dev/diskmap.c,v
> retrieving revision 1.20
> diff -u -p -r1.20 diskmap.c
> --- dev/diskmap.c 9 May 2018 08:42:02 -   1.20
> +++ dev/diskmap.c 20 Jun 2018 13:14:06 -
> @@ -57,9 +57,9 @@ diskmapioctl(dev_t dev, u_long cmd, cadd
>   struct dk_diskmap *dm;
>   struct nameidata ndp;
>   struct filedesc *fdp = p->p_fd;
> - struct file *fp = NULL;
> - struct vnode *vp = NULL, *ovp;
> - char *devname;
> + struct file *fp0 = NULL, *fp = NULL;
> + struct vnode *vp = NULL;
> + char *devname, flags;
>   int fd, error = EINVAL;
>  
>   if (cmd != DIOCMAP)
> @@ -80,57 +80,59 @@ diskmapioctl(dev_t dev, u_long cmd, cadd
>   goto invalid;
> 

DRI3/prime kernel implementation for OpenBSD

2018-06-20 Thread Mark Kettenis
This diff adds DRI3/prime support to the OpenBSD kernel.  The whole
idea behind this is to allow graphics buffers to be exchanged between
processes (typically X client and X server) by passing file
descriptors.  The curremt (DRI2) method of exchanging graphics buffers
uses guessable 32-bit integers.  That means that it is fairly easy for
other applications running on the machine to snoop the contents of a
graphics buffer.  Apart from the improved security, this also gets us
to execute the code paths in X, Mesa, etc. that Linux uses.  Hopefully
that makes us less susceptible to bugs in the abandoned codepaths.

This diff explicitly does not enable sharing of graphics buffers
between graphics cards.  That aspect of DRI3 needs more work.  It
would be pretty pointless at this point anyway since this only enables
the feature for inteldrm(4).

To actually use this, a xenocara patch is needed as well.  I'll post
that one in a separate message.

I've used this quite extensively now on my own laptop for a while.  It
works fine with pledged Chrome and pledged Firefox.  Now this collides
heavily with the file descriptor unlocking work that mpi@ is doing.
Still, I'd like to get this in soonish such that this can be widely
tested and won't ruin g2k18.

ok?


Index: dev/pci/drm/drmP.h
===
RCS file: /cvs/src/sys/dev/pci/drm/drmP.h,v
retrieving revision 1.217
diff -u -p -r1.217 drmP.h
--- dev/pci/drm/drmP.h  19 Feb 2018 08:59:52 -  1.217
+++ dev/pci/drm/drmP.h  20 Jun 2018 18:41:39 -
@@ -352,6 +352,12 @@ struct drm_pending_event {
void (*destroy)(struct drm_pending_event *event);
 };
 
+/* initial implementaton using a linked list - todo hashtab */
+struct drm_prime_file_private {
+   struct list_head head;
+   struct rwlock lock;
+};
+
 /** File private data */
 struct drm_file {
unsigned always_authenticated :1;
@@ -395,6 +401,8 @@ struct drm_file {
struct list_head event_list;
int event_space;
 
+   struct drm_prime_file_private prime;
+
struct selinfo rsel;
SPLAY_ENTRY(drm_file) link;
 };
@@ -480,6 +488,34 @@ struct drm_gem_object {
uint32_t pending_read_domains;
uint32_t pending_write_domain;
 
+   /**
+* dma_buf - dma buf associated with this GEM object
+*
+* Pointer to the dma-buf associated with this gem object (either
+* through importing or exporting). We break the resulting reference
+* loop when the last gem handle for this object is released.
+*
+* Protected by obj->object_name_lock
+*/
+   struct dma_buf *dma_buf;
+
+   /**
+* import_attach - dma buf attachment backing this object
+*
+* Any foreign dma_buf imported as a gem object has this set to the
+* attachment point for the device. This is invariant over the lifetime
+* of a gem object.
+*
+* The driver's ->gem_free_object callback is responsible for cleaning
+* up the dma_buf attachment and references acquired at import time.
+*
+* Note that the drm gem/prime core does not depend upon drivers setting
+* this field any more. So for drivers where this doesn't make sense
+* (e.g. virtual devices or a displaylink behind an usb bus) they can
+* simply leave it as NULL.
+*/
+   struct dma_buf_attachment *import_attach;
+
struct uvm_object uobj;
SPLAY_ENTRY(drm_gem_object) entry;
struct uvm_object *uao;
@@ -646,6 +682,20 @@ struct drm_driver {
int (*gem_fault)(struct drm_gem_object *, struct uvm_faultinfo *,
off_t, vaddr_t, vm_page_t *, int, int, vm_prot_t, int);
 
+   /* prime: */
+   /* export handle -> fd (see drm_gem_prime_handle_to_fd() helper) */
+   int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file 
*file_priv,
+   uint32_t handle, uint32_t flags, int *prime_fd);
+   /* import fd -> handle (see drm_gem_prime_fd_to_handle() helper) */
+   int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file 
*file_priv,
+   int prime_fd, uint32_t *handle);
+   /* export GEM -> dmabuf */
+   struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
+   struct drm_gem_object *obj, int flags);
+   /* import dmabuf -> GEM */
+   struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
+   struct dma_buf *dma_buf);
+
int (*dumb_create)(struct drm_file *file_priv,
struct drm_device *dev, struct drm_mode_create_dumb *args);
int (*dumb_map_offset)(struct drm_file *file_priv,
@@ -981,6 +1031,13 @@ static inline wait_queue_head_t *drm_crt
 /* Modesetting support */
 extern void drm_vblank_pre_modeset(struct drm_device *dev, unsigned int pipe);
 extern void d

DRI3/prime diff for xenocara

2018-06-20 Thread Mark Kettenis
This enables various DRI3-related bits in xenocara.  Matthieu warns me
that this will make the Mesa libraries depend on libxshmfence wich
he thinks will lead to WANTLIB churn in ports...

Is that going to be a problem?

Index: lib/Makefile
===
RCS file: /cvs/xenocara/lib/Makefile,v
retrieving revision 1.35
diff -u -p -r1.35 Makefile
--- lib/Makefile20 May 2018 09:40:53 -  1.35
+++ lib/Makefile20 Jun 2018 19:09:12 -
@@ -44,7 +44,7 @@ SUBDIR= freetype fontconfig libxtrans li
libXi libXinerama libxkbfile libxkbui  \
libXrandr libXRes libXScrnSaver \
libXtst libXv libXvMC libXxf86dga libXxf86vm \
-   libpciaccess pixman
+   libpciaccess libxshmfence pixman
 
 .if ${XENOCARA_BUILD_GL:L} == "yes"
 SUBDIR+= libdrm
Index: lib/mesa/Makefile.bsd-wrapper
===
RCS file: /cvs/xenocara/lib/mesa/Makefile.bsd-wrapper,v
retrieving revision 1.17
diff -u -p -r1.17 Makefile.bsd-wrapper
--- lib/mesa/Makefile.bsd-wrapper   21 Feb 2018 06:01:53 -  1.17
+++ lib/mesa/Makefile.bsd-wrapper   20 Jun 2018 19:09:14 -
@@ -30,6 +30,7 @@ CONFIGURE_ARGS=   --with-dri-drivers=${DR
--enable-osmesa \
--enable-gbm \
--enable-texture-float \
+   --enable-dri3 \
--with-egl-platforms="x11,drm" \
--prefix=${X11BASE} \
--with-dri-driverdir=${X11BASE}/lib/modules/dri \
Index: proto/Makefile
===
RCS file: /cvs/xenocara/proto/Makefile,v
retrieving revision 1.14
diff -u -p -r1.14 Makefile
--- proto/Makefile  20 May 2018 09:40:53 -  1.14
+++ proto/Makefile  20 Jun 2018 19:09:16 -
@@ -11,7 +11,7 @@ SUBDIR= bigreqsproto compositeproto dmxp
xf86vidmodeproto
 
 .if ${XENOCARA_BUILD_DRI:L} == "yes"
-SUBDIR+= xf86driproto dri2proto
+SUBDIR+= xf86driproto dri2proto dri3proto
 .endif
 
 .include 



Re: DRI3/prime kernel implementation for OpenBSD

2018-06-21 Thread Mark Kettenis
> Date: Thu, 21 Jun 2018 11:28:26 +1000
> From: Jonathan Gray 
> 
> On Wed, Jun 20, 2018 at 08:55:39PM +0200, Mark Kettenis wrote:
> > This diff adds DRI3/prime support to the OpenBSD kernel.  The whole
> > idea behind this is to allow graphics buffers to be exchanged between
> > processes (typically X client and X server) by passing file
> > descriptors.  The curremt (DRI2) method of exchanging graphics buffers
> > uses guessable 32-bit integers.  That means that it is fairly easy for
> > other applications running on the machine to snoop the contents of a
> > graphics buffer.  Apart from the improved security, this also gets us
> > to execute the code paths in X, Mesa, etc. that Linux uses.  Hopefully
> > that makes us less susceptible to bugs in the abandoned codepaths.
> > 
> > This diff explicitly does not enable sharing of graphics buffers
> > between graphics cards.  That aspect of DRI3 needs more work.  It
> > would be pretty pointless at this point anyway since this only enables
> > the feature for inteldrm(4).
> > 
> > To actually use this, a xenocara patch is needed as well.  I'll post
> > that one in a separate message.
> > 
> > I've used this quite extensively now on my own laptop for a while.  It
> > works fine with pledged Chrome and pledged Firefox.  Now this collides
> > heavily with the file descriptor unlocking work that mpi@ is doing.
> > Still, I'd like to get this in soonish such that this can be widely
> > tested and won't ruin g2k18.
> > 
> > ok?
> 
> So the radeon parts (radeon_prime.c etc) can come later as when
> DRIVER_PRIME/prime_fd_to_handle/prime_handle_to_fd etc are not set
> everything will fall back?
> 
> Though it seems DRIVER_PRIME is already set in radeon...

Probably best to remove that for now.  I'll integrate that into the diff.

Interestingly enough, the modesetting driver advertises DRI3 even of
the kernel driver doesn't support it.  As a result Mesa prints an
error message before it falls back to DRI2.  Guess we can live with
that.  With the xf86-video-ati driver that doesn't happen.

Going to look into adding support for this to radeon(4) anyway.

Cheers,

Mark

> > Index: dev/pci/drm/drmP.h
> > ===
> > RCS file: /cvs/src/sys/dev/pci/drm/drmP.h,v
> > retrieving revision 1.217
> > diff -u -p -r1.217 drmP.h
> > --- dev/pci/drm/drmP.h  19 Feb 2018 08:59:52 -  1.217
> > +++ dev/pci/drm/drmP.h  20 Jun 2018 18:41:39 -
> > @@ -352,6 +352,12 @@ struct drm_pending_event {
> > void (*destroy)(struct drm_pending_event *event);
> >  };
> >  
> > +/* initial implementaton using a linked list - todo hashtab */
> > +struct drm_prime_file_private {
> > +   struct list_head head;
> > +   struct rwlock lock;
> > +};
> > +
> >  /** File private data */
> >  struct drm_file {
> > unsigned always_authenticated :1;
> > @@ -395,6 +401,8 @@ struct drm_file {
> > struct list_head event_list;
> > int event_space;
> >  
> > +   struct drm_prime_file_private prime;
> > +
> > struct selinfo rsel;
> > SPLAY_ENTRY(drm_file) link;
> >  };
> > @@ -480,6 +488,34 @@ struct drm_gem_object {
> > uint32_t pending_read_domains;
> > uint32_t pending_write_domain;
> >  
> > +   /**
> > +* dma_buf - dma buf associated with this GEM object
> > +*
> > +* Pointer to the dma-buf associated with this gem object (either
> > +* through importing or exporting). We break the resulting reference
> > +* loop when the last gem handle for this object is released.
> > +*
> > +* Protected by obj->object_name_lock
> > +*/
> > +   struct dma_buf *dma_buf;
> > +
> > +   /**
> > +* import_attach - dma buf attachment backing this object
> > +*
> > +* Any foreign dma_buf imported as a gem object has this set to the
> > +* attachment point for the device. This is invariant over the lifetime
> > +* of a gem object.
> > +*
> > +* The driver's ->gem_free_object callback is responsible for cleaning
> > +* up the dma_buf attachment and references acquired at import time.
> > +*
> > +* Note that the drm gem/prime core does not depend upon drivers setting
> > +* this field any more. So for drivers where this doesn't make sense
> > +* (e.g. virtual devices or a displaylink behind an usb bus) they can
> > +* simply leave it as NULL.
> > +*/
> > +   stru

Use -z notext -z norelro for armv7 efiboot

2018-06-22 Thread Mark Kettenis
Creating relocations inside .text is inherent to the way we wrap an
ELF shared object inside a PE executable.  But without -z notext
lld(1) complains about this.  Also pass -z norelro to suppress the
creation of a separate rodata segment that makes lld(1) complain about
relocations against a read-only section.  This makes it possible to
build efiboot with lld(1) on armv7.

ok?


Index: arch/armv7/stand/efiboot/Makefile
===
RCS file: /cvs/src/sys/arch/armv7/stand/efiboot/Makefile,v
retrieving revision 1.10
diff -u -p -r1.10 Makefile
--- arch/armv7/stand/efiboot/Makefile   11 May 2018 11:58:59 -  1.10
+++ arch/armv7/stand/efiboot/Makefile   22 Jun 2018 09:56:53 -
@@ -17,7 +17,8 @@ EFIDIR=   ${S}/stand/efi
 OBJCOPY?=  objcopy
 OBJDUMP?=  objdump
 
-LDFLAGS+=-nostdlib -T ${.CURDIR}/ldscript.arm -Bsymbolic -shared
+LDFLAGS+=  -nostdlib -T ${.CURDIR}/ldscript.arm -Bsymbolic -shared
+LDFLAGS+=  -z notext -z norelro
 
 .PATH: ${S}/stand/boot
 SRCS+= boot.c cmd.c vars.c



Save and restore FPU state around signal handlers on armv7

2018-06-22 Thread Mark Kettenis
It takes the alpha/hppa/mips64 approach of storing the state in struct
sigcontext instead of using a pointer.  Using unsigned int and
unsigned long long instead of uint32_t and uint64_t here to avoid
having to include other headers.  But I suppose I could include
include  and use __uint32_t and __uint64_t if people
prefer that.

This is an ABI break.  Code that plays tricks with sigcontext, like
copying structs around or looks at the internals will have to be
recompiled.  But we don't really support that, so I'm inclined to just
go aead.

This fixes the corruption in ksh/sh that is currently preventing snaps
from being built.  At least in combination with the setjmp fix I
mailed out wednesday and Dale's ast fix.

ok?


Index: arch/arm/arm/sig_machdep.c
===
RCS file: /cvs/src/sys/arch/arm/arm/sig_machdep.c,v
retrieving revision 1.16
diff -u -p -r1.16 sig_machdep.c
--- arch/arm/arm/sig_machdep.c  12 Apr 2018 17:13:43 -  1.16
+++ arch/arm/arm/sig_machdep.c  22 Jun 2018 15:07:30 -
@@ -51,12 +51,13 @@
 #include 
 #include 
 
-#include 
-
 #include 
 #include 
 #include 
+
+#include 
 #include 
+#include 
 
 #include 
 
@@ -80,6 +81,7 @@ sendsig(sig_t catcher, int sig, int retu
union sigval val)
 {
struct proc *p = curproc;
+   struct pcb *pcb = &p->p_addr->u_pcb;
struct trapframe *tf;
struct sigframe *fp, frame;
struct sigacts *psp = p->p_p->ps_sigacts;
@@ -130,6 +132,15 @@ sendsig(sig_t catcher, int sig, int retu
/* Save signal mask. */
frame.sf_sc.sc_mask = returnmask;
 
+   /* Save FPU registers. */
+   frame.sf_sc.sc_fpused = pcb->pcb_flags & PCB_FPU;
+   if (frame.sf_sc.sc_fpused) {
+   frame.sf_sc.sc_fpscr = pcb->pcb_fpstate.fp_scr;
+   memcpy(&frame.sf_sc.sc_fpreg, &pcb->pcb_fpstate.fp_reg,
+  sizeof(pcb->pcb_fpstate.fp_reg));
+   pcb->pcb_flags &= ~PCB_FPU;
+   }
+
if (psp->ps_siginfo & sigmask(sig)) {
frame.sf_sip = &fp->sf_si;
initsiginfo(&frame.sf_si, sig, code, type, val);
@@ -176,6 +187,7 @@ sys_sigreturn(struct proc *p, void *v, r
syscallarg(struct sigcontext *) sigcntxp;
} */ *uap = v;
struct sigcontext ksc, *scp = SCARG(uap, sigcntxp);
+   struct pcb *pcb = &p->p_addr->u_pcb;
struct trapframe *tf;
 
if (PROC_PC(p) != p->p_p->ps_sigcoderet) {
@@ -227,6 +239,17 @@ sys_sigreturn(struct proc *p, void *v, r
 
/* Restore signal mask. */
p->p_sigmask = ksc.sc_mask & ~sigcantmask;
+
+   /* Restore FPU registers. */
+   if (ksc.sc_fpused) {
+   if (p->p_addr->u_pcb.pcb_fpcpu != NULL)
+   vfp_discard(p);
+
+   pcb->pcb_fpstate.fp_scr = ksc.sc_fpscr;
+   memcpy(&pcb->pcb_fpstate.fp_reg, &ksc.sc_fpreg,
+   sizeof(pcb->pcb_fpstate.fp_reg));
+   pcb->pcb_flags |= PCB_FPU;
+   }
 
return (EJUSTRETURN);
 }
Index: arch/arm/include/signal.h
===
RCS file: /cvs/src/sys/arch/arm/include/signal.h,v
retrieving revision 1.9
diff -u -p -r1.9 signal.h
--- arch/arm/include/signal.h   10 May 2016 18:39:43 -  1.9
+++ arch/arm/include/signal.h   22 Jun 2018 15:07:30 -
@@ -82,6 +82,10 @@ struct sigcontext {
unsigned int sc_usr_lr;
unsigned int sc_svc_lr;
unsigned int sc_pc;
+
+   unsigned int sc_fpused;
+   unsigned int sc_fpscr;
+   unsigned long long sc_fpreg[32];
 };
 #endif /* __BSD_VISIBLE || __XPG_VISIBLE >= 420 */
 #endif /* !_LOCORE */



Re: DRI3/prime kernel implementation for OpenBSD

2018-06-22 Thread Mark Kettenis
And here is a version that supports radeon(4) as well.

Still looking for oks...


Index: dev/pci/drm/drmP.h
===
RCS file: /cvs/src/sys/dev/pci/drm/drmP.h,v
retrieving revision 1.217
diff -u -p -r1.217 drmP.h
--- dev/pci/drm/drmP.h  19 Feb 2018 08:59:52 -  1.217
+++ dev/pci/drm/drmP.h  22 Jun 2018 20:58:06 -
@@ -352,6 +352,12 @@ struct drm_pending_event {
void (*destroy)(struct drm_pending_event *event);
 };
 
+/* initial implementaton using a linked list - todo hashtab */
+struct drm_prime_file_private {
+   struct list_head head;
+   struct rwlock lock;
+};
+
 /** File private data */
 struct drm_file {
unsigned always_authenticated :1;
@@ -395,6 +401,8 @@ struct drm_file {
struct list_head event_list;
int event_space;
 
+   struct drm_prime_file_private prime;
+
struct selinfo rsel;
SPLAY_ENTRY(drm_file) link;
 };
@@ -480,6 +488,34 @@ struct drm_gem_object {
uint32_t pending_read_domains;
uint32_t pending_write_domain;
 
+   /**
+* dma_buf - dma buf associated with this GEM object
+*
+* Pointer to the dma-buf associated with this gem object (either
+* through importing or exporting). We break the resulting reference
+* loop when the last gem handle for this object is released.
+*
+* Protected by obj->object_name_lock
+*/
+   struct dma_buf *dma_buf;
+
+   /**
+* import_attach - dma buf attachment backing this object
+*
+* Any foreign dma_buf imported as a gem object has this set to the
+* attachment point for the device. This is invariant over the lifetime
+* of a gem object.
+*
+* The driver's ->gem_free_object callback is responsible for cleaning
+* up the dma_buf attachment and references acquired at import time.
+*
+* Note that the drm gem/prime core does not depend upon drivers setting
+* this field any more. So for drivers where this doesn't make sense
+* (e.g. virtual devices or a displaylink behind an usb bus) they can
+* simply leave it as NULL.
+*/
+   struct dma_buf_attachment *import_attach;
+
struct uvm_object uobj;
SPLAY_ENTRY(drm_gem_object) entry;
struct uvm_object *uao;
@@ -646,6 +682,20 @@ struct drm_driver {
int (*gem_fault)(struct drm_gem_object *, struct uvm_faultinfo *,
off_t, vaddr_t, vm_page_t *, int, int, vm_prot_t, int);
 
+   /* prime: */
+   /* export handle -> fd (see drm_gem_prime_handle_to_fd() helper) */
+   int (*prime_handle_to_fd)(struct drm_device *dev, struct drm_file 
*file_priv,
+   uint32_t handle, uint32_t flags, int *prime_fd);
+   /* import fd -> handle (see drm_gem_prime_fd_to_handle() helper) */
+   int (*prime_fd_to_handle)(struct drm_device *dev, struct drm_file 
*file_priv,
+   int prime_fd, uint32_t *handle);
+   /* export GEM -> dmabuf */
+   struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
+   struct drm_gem_object *obj, int flags);
+   /* import dmabuf -> GEM */
+   struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
+   struct dma_buf *dma_buf);
+
int (*dumb_create)(struct drm_file *file_priv,
struct drm_device *dev, struct drm_mode_create_dumb *args);
int (*dumb_map_offset)(struct drm_file *file_priv,
@@ -981,6 +1031,18 @@ static inline wait_queue_head_t *drm_crt
 /* Modesetting support */
 extern void drm_vblank_pre_modeset(struct drm_device *dev, unsigned int pipe);
 extern void drm_vblank_post_modeset(struct drm_device *dev, unsigned int pipe);
+
+extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
+   struct drm_gem_object *obj,
+   int flags);
+extern int drm_gem_prime_handle_to_fd(struct drm_device *dev,
+   struct drm_file *file_priv, uint32_t handle, uint32_t flags,
+   int *prime_fd);
+extern struct drm_gem_object *drm_gem_prime_import(struct drm_device *dev,
+   struct dma_buf *dma_buf);
+extern int drm_gem_prime_fd_to_handle(struct drm_device *dev,
+   struct drm_file *file_priv, int prime_fd, uint32_t *handle);
+extern void drm_gem_dmabuf_release(struct dma_buf *dma_buf);
 
 bool   drm_mode_parse_command_line_for_connector(const char *,
struct drm_connector *, struct drm_cmdline_mode *);
Index: dev/pci/drm/drm_drv.c
===
RCS file: /cvs/src/sys/dev/pci/drm/drm_drv.c,v
retrieving revision 1.157
diff -u -p -r1.157 drm_drv.c
--- dev/pci/drm/drm_drv.c   31 Jan 2018 05:04:41 -  1.157
+++ dev/pci/drm/drm_drv.c 

Re: Save and restore FPU state around signal handlers on armv7

2018-06-22 Thread Mark Kettenis
> Date: Fri, 22 Jun 2018 17:16:14 +0200 (CEST)
> From: Mark Kettenis 
> 
> It takes the alpha/hppa/mips64 approach of storing the state in struct
> sigcontext instead of using a pointer.  Using unsigned int and
> unsigned long long instead of uint32_t and uint64_t here to avoid
> having to include other headers.  But I suppose I could include
> include  and use __uint32_t and __uint64_t if people
> prefer that.
> 
> This is an ABI break.  Code that plays tricks with sigcontext, like
> copying structs around or looks at the internals will have to be
> recompiled.  But we don't really support that, so I'm inclined to just
> go aead.
> 
> This fixes the corruption in ksh/sh that is currently preventing snaps
> from being built.  At least in combination with the setjmp fix I
> mailed out wednesday and Dale's ast fix.
> 
> ok?

Better diff that gives the signal handler a clean FPU state and make
sure we reset the FPU state if the signal handler was the first to use
the FPU.  This no longer calls vfp_discard().  Instead it just sets
pcb_fpcpu to NULL.  That is enough to force reloading of the FPU
state.

ok?


Index: arch/arm/arm/sig_machdep.c
===
RCS file: /cvs/src/sys/arch/arm/arm/sig_machdep.c,v
retrieving revision 1.16
diff -u -p -r1.16 sig_machdep.c
--- arch/arm/arm/sig_machdep.c  12 Apr 2018 17:13:43 -  1.16
+++ arch/arm/arm/sig_machdep.c  22 Jun 2018 22:10:19 -
@@ -51,11 +51,11 @@
 #include 
 #include 
 
-#include 
-
 #include 
 #include 
 #include 
+
+#include 
 #include 
 
 #include 
@@ -80,6 +80,7 @@ sendsig(sig_t catcher, int sig, int retu
union sigval val)
 {
struct proc *p = curproc;
+   struct pcb *pcb = &p->p_addr->u_pcb;
struct trapframe *tf;
struct sigframe *fp, frame;
struct sigacts *psp = p->p_p->ps_sigacts;
@@ -130,6 +131,16 @@ sendsig(sig_t catcher, int sig, int retu
/* Save signal mask. */
frame.sf_sc.sc_mask = returnmask;
 
+   /* Save FPU registers. */
+   frame.sf_sc.sc_fpused = pcb->pcb_flags & PCB_FPU;
+   if (frame.sf_sc.sc_fpused) {
+   frame.sf_sc.sc_fpscr = pcb->pcb_fpstate.fp_scr;
+   memcpy(&frame.sf_sc.sc_fpreg, &pcb->pcb_fpstate.fp_reg,
+  sizeof(pcb->pcb_fpstate.fp_reg));
+   pcb->pcb_flags &= ~PCB_FPU;
+   pcb->pcb_fpcpu = NULL;
+   }
+
if (psp->ps_siginfo & sigmask(sig)) {
frame.sf_sip = &fp->sf_si;
initsiginfo(&frame.sf_si, sig, code, type, val);
@@ -176,6 +187,7 @@ sys_sigreturn(struct proc *p, void *v, r
syscallarg(struct sigcontext *) sigcntxp;
} */ *uap = v;
struct sigcontext ksc, *scp = SCARG(uap, sigcntxp);
+   struct pcb *pcb = &p->p_addr->u_pcb;
struct trapframe *tf;
 
if (PROC_PC(p) != p->p_p->ps_sigcoderet) {
@@ -227,6 +239,18 @@ sys_sigreturn(struct proc *p, void *v, r
 
/* Restore signal mask. */
p->p_sigmask = ksc.sc_mask & ~sigcantmask;
+
+   /* Restore FPU registers. */
+   if (ksc.sc_fpused) {
+   pcb->pcb_fpstate.fp_scr = ksc.sc_fpscr;
+   memcpy(&pcb->pcb_fpstate.fp_reg, &ksc.sc_fpreg,
+   sizeof(pcb->pcb_fpstate.fp_reg));
+   pcb->pcb_flags |= PCB_FPU;
+   pcb->pcb_fpcpu = NULL;
+   } else {
+   pcb->pcb_flags &= ~PCB_FPU;
+   pcb->pcb_fpcpu = NULL;
+   }
 
return (EJUSTRETURN);
 }
Index: arch/arm/include/signal.h
===
RCS file: /cvs/src/sys/arch/arm/include/signal.h,v
retrieving revision 1.9
diff -u -p -r1.9 signal.h
--- arch/arm/include/signal.h   10 May 2016 18:39:43 -  1.9
+++ arch/arm/include/signal.h   22 Jun 2018 22:10:19 -
@@ -82,6 +82,10 @@ struct sigcontext {
unsigned int sc_usr_lr;
unsigned int sc_svc_lr;
unsigned int sc_pc;
+
+   unsigned int sc_fpused;
+   unsigned int sc_fpscr;
+   unsigned long long sc_fpreg[32];
 };
 #endif /* __BSD_VISIBLE || __XPG_VISIBLE >= 420 */
 #endif /* !_LOCORE */



ACPI on OpenBSD/arm64

2018-06-23 Thread Mark Kettenis
The lates generation of 64-bit ARM server hardware seems to be
ACPI-only.  This obviously fills me with a tremendous amount of joy.
ACPi is clearly superior to device trees.  So much more superior that
they you have to embed snippets of device tree properties into your
AML to make it do anything useful on stuff that isn't 100%
bog-standard hardware [1].

Well, enough sarcasm.  Maybe this is even a good thing since it
encourages ARM server vendors from being too creative and simply stick
everything of interest behind a PCIe host bridge.

I have some ideas on how to support ACPI on OpenBSD/arm64.  As a first
stap, I'd like to make acpidump(4) work.  The diff below adds a little
bit of kernel code to stick the address where the ACPI tables can be
found into a global variable.

ok?


[1] https://lwn.net/Articles/612062/

Index: dev/acpi/efi.h
===
RCS file: /cvs/src/sys/dev/acpi/efi.h,v
retrieving revision 1.2
diff -u -p -r1.2 efi.h
--- dev/acpi/efi.h  4 Jan 2018 14:30:08 -   1.2
+++ dev/acpi/efi.h  23 Jun 2018 14:13:57 -
@@ -13,7 +13,6 @@ typedef uint64_t  UINT64;
 typedef u_long UINTN;
 typedef uint16_t   CHAR16;
 typedef void   VOID;
-typedef uint32_t   EFI_GUID[4];
 typedef uint64_t   EFI_PHYSICAL_ADDRESS;
 typedef uint64_t   EFI_VIRTUAL_ADDRESS;
 typedef UINTN  EFI_STATUS;
@@ -23,6 +22,17 @@ typedef VOID *EFI_SIMPLE_TEXT_INPUT_PRO
 typedef VOID   *EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL;
 typedef VOID   *EFI_BOOT_SERVICES;
 
+typedef struct {
+   UINT32  Data1;
+   UINT16  Data2;
+   UINT16  Data3;
+   UINT8   Data4[8];
+} EFI_GUID;
+
+#define EFI_ACPI_20_TABLE_GUID \
+  { 0x8868e871, 0xe4f1, 0x11d3, \
+{ 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81} }
+
 typedef enum {
EfiReservedMemoryType,
EfiLoaderCode,
@@ -130,4 +140,6 @@ typedef struct {
 
 #define EFI_SUCCESS0
 
-#endif /* _MACHINE_EFI_H_ */
+#defineefi_guidcmp(_a, _b) memcmp((_a), (_b), sizeof(EFI_GUID))
+
+#endif /* _DEV_ACPI_EFI_H_ */
Index: arch/arm64/dev/efi.c
===
RCS file: /cvs/src/sys/arch/arm64/dev/efi.c,v
retrieving revision 1.4
diff -u -p -r1.4 efi.c
--- arch/arm64/dev/efi.c6 Apr 2018 19:09:05 -   1.4
+++ arch/arm64/dev/efi.c23 Jun 2018 14:13:57 -
@@ -41,6 +41,8 @@ extern uint32_t mmap_desc_ver;
 
 extern EFI_MEMORY_DESCRIPTOR *mmap;
 
+uint64_t efi_acpi_table;
+
 struct efi_softc {
struct device   sc_dev;
struct pmap *sc_pm;
@@ -168,18 +170,25 @@ efi_attach(struct device *parent, struct
}
 
/*
-* The FirmwareVendor field has been converted from a physical
-* pointer to a virtual pointer, so we have to activate our
-* pmap to access it.
+* The FirmwareVendor and ConfigurationTable fields have been
+* converted from a physical pointer to a virtual pointer, so
+* we have to activate our pmap to access them.
 */
+   efi_enter(sc);
if (st->FirmwareVendor) {
printf("%s: ", sc->sc_dev.dv_xname);
-   efi_enter(sc);
for (i = 0; st->FirmwareVendor[i]; i++)
printf("%c", st->FirmwareVendor[i]);
-   efi_leave(sc);
printf(" rev 0x%x\n", st->FirmwareRevision);
}
+   for (i = 0; i < st->NumberOfTableEntries; i++) {
+   EFI_CONFIGURATION_TABLE *ct = &st->ConfigurationTable[i];
+   static EFI_GUID acpi_guid = EFI_ACPI_20_TABLE_GUID;
+
+   if (efi_guidcmp(&acpi_guid, &ct->VendorGuid) == 0)
+   efi_acpi_table = (uint64_t)ct->VendorTable;
+   }
+   efi_leave(sc);
 
if (rs == NULL)
return;
@@ -278,4 +287,3 @@ efi_settime(struct todr_chip_handle *han
return EIO;
return 0;
 }
-



Add XSDT and arm64 support to acpidump(8)

2018-06-23 Thread Mark Kettenis
The diff below adds arm64 support to acpidump(8).  It renames
bios_acpi_addr() into efi_acpi_addr() and duplicates the function
because on arm64 I just need to read a 64-bit integer I'm considering
changing amd64 to use a variable with the same name to get rid of the
#ifdef.  The code that grovels through low memory to discover the ACPI
tables is only enabled for amd64 and i386 now.

Since on my arm64 system there is no RSDT, this adds support for using
the XSDT instead.  There is a fair bit of code reorg to handle the
discovery of the RSD PTR table as the pointer to the XSDT won't be
there on ACPI 1.0 systems.

ok?


Index: usr.sbin/acpidump/Makefile
===
RCS file: /cvs/src/usr.sbin/acpidump/Makefile,v
retrieving revision 1.6
diff -u -p -r1.6 Makefile
--- usr.sbin/acpidump/Makefile  24 Jan 2017 00:20:28 -  1.6
+++ usr.sbin/acpidump/Makefile  23 Jun 2018 14:37:02 -
@@ -1,6 +1,7 @@
 # $OpenBSD: Makefile,v 1.6 2017/01/24 00:20:28 deraadt Exp $
 
-.if (${MACHINE} == "i386") || (${MACHINE} == "amd64")
+.if ${MACHINE} == "amd64" || ${MACHINE} == "arm64" || \
+${MACHINE} == "i386"
 PROG= acpidump
 SRCS= acpidump.c
 LDADD= -lkvm
Index: usr.sbin/acpidump/acpidump.c
===
RCS file: /cvs/src/usr.sbin/acpidump/acpidump.c,v
retrieving revision 1.17
diff -u -p -r1.17 acpidump.c
--- usr.sbin/acpidump/acpidump.c26 Sep 2016 19:58:26 -  1.17
+++ usr.sbin/acpidump/acpidump.c23 Jun 2018 14:37:02 -
@@ -30,7 +30,6 @@
 #include 
 #include 
 #include 
-#include 
 
 #include 
 #include 
@@ -58,8 +57,13 @@ struct ACPIrsdp {
u_char  signature[8];
u_char  sum;
u_char  oem[6];
-   u_char  res;
+   u_char  rev;
u_int32_t   addr;
+#define SIZEOF_RSDP_REV_0  20
+   u_int32_t   len;
+   u_int64_t   xaddr;
+   u_char  xsum;
+   u_char  xres[3];
 } __packed;
 
 struct ACPIsdt {
@@ -174,6 +178,7 @@ int acpi_checksum(void *_p, size_t _leng
 struct acpi_user_mapping *acpi_user_find_mapping(vm_offset_t _pa, size_t 
_size);
 void   *acpi_map_physical(vm_offset_t _pa, size_t _size);
 void   acpi_user_init(void);
+struct ACPIrsdp *acpi_check_rsd_ptr(vm_offset_t _pa);
 struct ACPIrsdp *acpi_find_rsd_ptr(void);
 void   acpi_print_string(char *_s, size_t _length);
 void   acpi_print_rsd_ptr(struct ACPIrsdp *_rp);
@@ -181,14 +186,16 @@ struct ACPIsdt *acpi_map_sdt(vm_offset_t
 void   aml_dump(struct ACPIsdt *_hdr);
 void   acpi_print_sdt(struct ACPIsdt *_sdp);
 void   acpi_print_rsdt(struct ACPIsdt *_rsdp);
+void   acpi_print_xsdt(struct ACPIsdt *_rsdp);
 void   acpi_print_facp(struct FACPbody *_facp);
 void   acpi_print_dsdt(struct ACPIsdt *_dsdp);
 void   acpi_handle_dsdt(struct ACPIsdt *_dsdp);
 void   acpi_handle_facp(struct FACPbody *_facp);
 void   acpi_handle_rsdt(struct ACPIsdt *_rsdp);
+void   acpi_handle_xsdt(struct ACPIsdt *_rsdp);
 void   asl_dump_from_devmem(void);
 void   usage(void);
-u_long bios_acpi_addr(void);
+u_long efi_acpi_addr(void);
 
 
 struct ACPIsdt dsdt_header = {
@@ -264,41 +271,47 @@ acpi_user_init(void)
 }
 
 struct ACPIrsdp *
+acpi_check_rsd_ptr(vm_offset_t pa)
+{
+   struct ACPIrsdp rp;
+   
+   lseek(acpi_mem_fd, pa, SEEK_SET);
+   read(acpi_mem_fd, &rp, SIZEOF_RSDP_REV_0);
+   if (memcmp(rp.signature, "RSD PTR ", 8) != 0)
+   return NULL;
+
+   if (rp.rev >= 2) {
+   read(acpi_mem_fd, &(rp.len),
+   sizeof(struct ACPIrsdp) - SIZEOF_RSDP_REV_0);
+   if (acpi_checksum(&rp, sizeof(struct ACPIrsdp)) == 0)
+   return acpi_map_physical(pa, sizeof(struct ACPIrsdp));
+   }
+
+   if (acpi_checksum(&rp, SIZEOF_RSDP_REV_0) == 0)
+   return (acpi_map_physical(pa, SIZEOF_RSDP_REV_0));
+
+   return NULL;
+}
+
+struct ACPIrsdp *
 acpi_find_rsd_ptr(void)
 {
-   int i;
-   u_int8_tbuf[sizeof(struct ACPIrsdp)];
+   struct ACPIrsdp *rp;
u_long  addr;
 
-   if ((addr = bios_acpi_addr()) != 0) {
-   lseek(acpi_mem_fd, addr, SEEK_SET);
-   read(acpi_mem_fd, buf, 16);
-   if (!memcmp(buf, "RSD PTR ", 8)) {
-   read(acpi_mem_fd, buf + 16,
-   sizeof(struct ACPIrsdp) - 16);
-   if (!acpi_checksum(buf, sizeof(struct ACPIrsdp)))
-   return (acpi_map_physical(addr,
-   sizeof(struct ACPIrsdp)));
-   }
-   lseek(acpi_mem_fd, 0, SEEK_SET);
+   if ((addr = efi_acpi_addr()) != 0) {
+   if ((rp = acpi_check_rsd_ptr(addr)))
+   return rp;
}
-   for (i = 0; i < 1024 * 1024; i += 16) {
-   lseek(acpi_mem_fd, i, SEEK_SET);
-   read(a

Rearrange the acpi(4) deck chairs

2018-06-24 Thread Mark Kettenis
The diff below shuffles things around to make it easier to add arm64
support later.  The main thing is to avoid including
 in , since that header file
doesn't exist on arm64.  The bulk of acpi_attach() is split out into a
new function and the current acpi_match() and acpi_attach() functions
are compiled on amd64 and i386 only.

ok?


Index: arch/amd64/amd64/acpi_machdep.c
===
RCS file: /cvs/src/sys/arch/amd64/amd64/acpi_machdep.c,v
retrieving revision 1.81
diff -u -p -r1.81 acpi_machdep.c
--- arch/amd64/amd64/acpi_machdep.c 5 Jun 2018 06:39:10 -   1.81
+++ arch/amd64/amd64/acpi_machdep.c 24 Jun 2018 21:58:24 -
@@ -95,6 +95,20 @@ acpi_unmap(struct acpi_mem_map *handle)
uvm_km_free(kernel_map, handle->baseva, handle->vsize);
 }
 
+int
+acpi_bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
+int flags, bus_space_handle_t *bshp)
+{
+   return _bus_space_map(t, addr, size, flags, bshp);
+}
+
+void
+acpi_bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
+bus_size_t size)
+{
+   _bus_space_unmap(t, bsh, size, NULL);
+}
+
 void *
 acpi_intr_establish(int irq, int flags, int level,
 int (*handler)(void *), void *arg, const char *what)
Index: arch/amd64/amd64/hibernate_machdep.c
===
RCS file: /cvs/src/sys/arch/amd64/amd64/hibernate_machdep.c,v
retrieving revision 1.42
diff -u -p -r1.42 hibernate_machdep.c
--- arch/amd64/amd64/hibernate_machdep.c21 Jun 2018 07:33:30 -  
1.42
+++ arch/amd64/amd64/hibernate_machdep.c24 Jun 2018 21:58:24 -
@@ -28,11 +28,10 @@
 #include 
 #include 
 
-#include 
-
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -41,6 +40,8 @@
 #ifdef MULTIPROCESSOR
 #include 
 #endif /* MULTIPROCESSOR */
+
+#include 
 
 #include "acpi.h"
 #include "wd.h"
Index: arch/i386/i386/acpi_machdep.c
===
RCS file: /cvs/src/sys/arch/i386/i386/acpi_machdep.c,v
retrieving revision 1.65
diff -u -p -r1.65 acpi_machdep.c
--- arch/i386/i386/acpi_machdep.c   31 Mar 2018 13:45:03 -  1.65
+++ arch/i386/i386/acpi_machdep.c   24 Jun 2018 21:58:24 -
@@ -28,6 +28,7 @@
 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -102,6 +103,20 @@ acpi_unmap(struct acpi_mem_map *handle)
 {
pmap_kremove(handle->baseva, handle->vsize);
uvm_km_free(kernel_map, handle->baseva, handle->vsize);
+}
+
+int
+acpi_bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
+int flags, bus_space_handle_t *bshp)
+{
+   return _bus_space_map(t, addr, size, flags, bshp);
+}
+
+void
+acpi_bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
+bus_size_t size)
+{
+   _bus_space_unmap(t, bsh, size, NULL);
 }
 
 u_int8_t *
Index: arch/i386/i386/hibernate_machdep.c
===
RCS file: /cvs/src/sys/arch/i386/i386/hibernate_machdep.c,v
retrieving revision 1.52
diff -u -p -r1.52 hibernate_machdep.c
--- arch/i386/i386/hibernate_machdep.c  21 Jun 2018 07:33:30 -  1.52
+++ arch/i386/i386/hibernate_machdep.c  24 Jun 2018 21:58:24 -
@@ -26,11 +26,10 @@
 #include 
 #include 
 
-#include 
-
 #include 
 #include 
 
+#include 
 #include 
 #include 
 #include 
@@ -39,6 +38,8 @@
 #ifdef MULTIPROCESSOR
 #include 
 #endif /* MULTIPROCESSOR */
+
+#include 
 
 #include "acpi.h"
 #include "wd.h"
Index: dev/acpi/acpi.c
===
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.344
diff -u -p -r1.344 acpi.c
--- dev/acpi/acpi.c 20 May 2018 09:12:35 -  1.344
+++ dev/acpi/acpi.c 24 Jun 2018 21:58:25 -
@@ -79,8 +79,6 @@ pcireg_t acpi_pci_min_powerstate(pci_chi
 voidacpi_pci_set_powerstate(pci_chipset_tag_t, pcitag_t, int, int);
 intacpi_pci_notify(struct aml_node *, int, void *);
 
-intacpi_match(struct device *, void *, void *);
-void   acpi_attach(struct device *, struct device *, void *);
 intacpi_submatch(struct device *, void *, void *);
 intacpi_print(void *, const char *);
 
@@ -198,21 +196,55 @@ static const char *sbtn_pnp[] = {
 intmouse_has_softbtn;
 #endif /* SMALL_KERNEL */
 
+struct acpi_softc *acpi_softc;
+
 /* XXX move this into dsdt softc at some point */
 extern struct aml_node aml_root;
 
+struct cfdriver acpi_cd = {
+   NULL, "acpi", DV_DULL
+};
+
+#if defined(__amd64__) || defined(__i386__)
+
+#include 
+
+intacpi_match(struct device *, void *, void *);
+void   acpi_attach(struct device *, struct device *, void *);
+
 struct cfattach acpi_ca = {
sizeof(struct acpi_softc), acpi_match, acpi_attach
 };
 
-struct cfdriver acpi_cd = {
-   NULL, "acpi", DV_DULL
-};
+int
+acpi_match(struct device *parent, void *match, void *aux)
+{
+   struct bios_attach_args *ba = aux;
+   st

Let acpi(4) pass down the bus dma tag

2018-06-25 Thread Mark Kettenis
When I added support for sdhc@acpi I made an ugly hack and directly
referenced the bus dma tag in a MD-specific fashion.  That is not
going to work for arm64.  And for arm64 I'll be needing the tag a lot
more.  So set it in amd64/i386-specific code and pass it down.

ok?


Index: dev/acpi/acpi.c
===
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.345
diff -u -p -r1.345 acpi.c
--- dev/acpi/acpi.c 25 Jun 2018 22:33:24 -  1.345
+++ dev/acpi/acpi.c 25 Jun 2018 23:02:46 -
@@ -240,6 +240,7 @@ acpi_attach(struct device *parent, struc
 
sc->sc_iot = ba->ba_iot;
sc->sc_memt = ba->ba_memt;
+   sc->sc_dmat = &pci_bus_dma_tag;
 
acpi_attach_common(sc, ba->ba_acpipbase);
 }
@@ -3006,6 +3007,7 @@ acpi_foundhid(struct aml_node *node, voi
memset(&aaa, 0, sizeof(aaa));
aaa.aaa_iot = sc->sc_iot;
aaa.aaa_memt = sc->sc_memt;
+   aaa.aaa_dmat = sc->sc_dmat;
aaa.aaa_node = node->parent;
aaa.aaa_dev = dev;
 
Index: dev/acpi/acpivar.h
===
RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.91
diff -u -p -r1.91 acpivar.h
--- dev/acpi/acpivar.h  25 Jun 2018 22:33:24 -  1.91
+++ dev/acpi/acpivar.h  25 Jun 2018 23:02:46 -
@@ -57,6 +57,7 @@ struct acpi_attach_args {
char*aaa_name;
bus_space_tag_t  aaa_iot;
bus_space_tag_t  aaa_memt;
+   bus_dma_tag_taaa_dmat;
void*aaa_table;
struct aml_node *aaa_node;
const char  *aaa_dev;
@@ -204,10 +205,7 @@ struct acpi_softc {
 
bus_space_tag_t sc_iot;
bus_space_tag_t sc_memt;
-#if 0
-   bus_space_tag_t sc_pcit;
-   bus_space_tag_t sc_smbust;
-#endif
+   bus_dma_tag_t   sc_dmat;
 
/*
 * First-level ACPI tables
Index: dev/acpi/sdhc_acpi.c
===
RCS file: /cvs/src/sys/dev/acpi/sdhc_acpi.c,v
retrieving revision 1.11
diff -u -p -r1.11 sdhc_acpi.c
--- dev/acpi/sdhc_acpi.c22 May 2018 21:17:13 -  1.11
+++ dev/acpi/sdhc_acpi.c25 Jun 2018 23:02:46 -
@@ -29,8 +29,6 @@
 #include 
 #include 
 
-extern struct bus_dma_tag pci_bus_dma_tag;
-
 struct sdhc_acpi_softc {
struct sdhc_softc sc;
struct acpi_softc *sc_acpi;
@@ -142,7 +140,7 @@ sdhc_acpi_attach(struct device *parent, 
sdhc_acpi_explore(sc);
 
sc->sc.sc_host = &sc->sc_host;
-   sc->sc.sc_dmat = &pci_bus_dma_tag;
+   sc->sc.sc_dmat = aaa->aaa_dmat;
sdhc_host_found(&sc->sc, sc->sc_memt, sc->sc_memh, sc->sc_size, 1, 0);
 }
 



Re: acpi: don't fail GPE handler re-registration

2018-06-25 Thread Mark Kettenis
> Date: Mon, 25 Jun 2018 21:02:38 -0700
> From: Mike Larkin 
> 
> Linux seems to permit GPE re-assignment (at least from what I can
> tell, the code is a bit convoluted). In the Surface Book AML,
> Microsoft provides an _L50 method as well as a _GPE method on the EC
> object that also returns 0x50.  This makes no sense, since EC GPEs
> must be edge-triggered (and an _Lxx method indicates a
> level-triggered GPE). What happens now is that we ignore the second
> GPE registration, meaning all EC GPEs get ignored.
> 
> This diff removes the -EBUSY return in that situation, allowing the second
> (and, I suppose, subsequent) GPEs to be registered properly.
> 
> With this diff, and another one not yet posted, I can get the EC on the
> Surface Book to actually generate events, which means we can support the 
> buttons and other events on this machine.
> 
> I am still not 100% convinced this is the right way to go. I have not yet
> unravelled all the Linux GPE code, but I'd like to see if the diff below
> breaks anyone, in case I decide to go this way. I have discussed this
> with kettenis@ and we can't come up with anything better at the moment.
> 
> Testing appreciated, look for "GPE xxx already enabled" in your dmesgs.

I think you should just commit this (keeping the printf).

ok kettenis@

> Index: acpi.c
> ===
> RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
> retrieving revision 1.345
> diff -u -p -a -u -r1.345 acpi.c
> --- acpi.c25 Jun 2018 22:33:24 -  1.345
> +++ acpi.c26 Jun 2018 03:36:10 -
> @@ -2186,10 +2186,9 @@ acpi_set_gpehandler(struct acpi_softc *s
>   ptbl = acpi_find_gpe(sc, gpe);
>   if (ptbl == NULL || handler == NULL)
>   return -EINVAL;
> - if (ptbl->handler != NULL) {
> - dnprintf(10, "error: GPE %.2x already enabled\n", gpe);
> - return -EBUSY;
> - }
> + if (ptbl->handler != NULL)
> + printf("%s: GPE %.2x already enabled\n", DEVNAME(sc), gpe);
> +
>   dnprintf(50, "Adding GPE handler %.2x (%s)\n", gpe, edge ? "edge" : 
> "level");
>   ptbl->handler = handler;
>   ptbl->arg = arg;
> 
> 



com@acpi

2018-06-30 Thread Mark Kettenis
vent(struct acpi_softc *, u_int);
 
 void   acpi_addtask(struct acpi_softc *, void (*)(void *, int), void *, int);
Index: dev/acpi/com_acpi.c
===
RCS file: dev/acpi/com_acpi.c
diff -N dev/acpi/com_acpi.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dev/acpi/com_acpi.c 30 Jun 2018 12:24:16 -
@@ -0,0 +1,184 @@
+/* $OpenBSD$   */
+/*
+ * Copyright (c) 2018 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#undef DEVNAME
+#include 
+#include 
+#include 
+
+#define com_usr 31 /* Synopsys DesignWare UART */
+
+struct com_acpi_softc {
+   struct com_softc sc;
+   struct acpi_softc *sc_acpi;
+   struct aml_node *sc_node;
+
+   bus_addr_t sc_addr;
+   bus_size_t sc_size;
+
+   int sc_irq;
+   int sc_irq_flags;
+   void *sc_ih;
+};
+
+intcom_acpi_match(struct device *, void *, void *);
+void   com_acpi_attach(struct device *, struct device *, void *);
+
+struct cfattach com_acpi_ca = {
+   sizeof(struct com_acpi_softc), com_acpi_match, com_acpi_attach
+};
+
+const char *com_hids[] = {
+   "HISI0031",
+   NULL
+};
+
+intcom_acpi_parse_resources(int, union acpi_resource *, void *);
+intcom_acpi_is_console(struct com_acpi_softc *);
+intcom_acpi_intr_designware(void *);
+
+int
+com_acpi_match(struct device *parent, void *match, void *aux)
+{
+   struct acpi_attach_args *aaa = aux;
+   struct cfdata *cf = match;
+
+   return acpi_matchhids(aaa, com_hids, cf->cf_driver->cd_name);
+}
+
+void
+com_acpi_attach(struct device *parent, struct device *self, void *aux)
+{
+   struct acpi_attach_args *aaa = aux;
+   struct com_acpi_softc *sc = (struct com_acpi_softc *)self;
+   struct aml_value res;
+   uint32_t freq;
+
+   sc->sc_acpi = (struct acpi_softc *)parent;
+   sc->sc_node = aaa->aaa_node;
+   printf(": %s", sc->sc_node->name);
+
+   if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) {
+   printf(": can't find registers\n");
+   return;
+   }
+
+   aml_parse_resource(&res, com_acpi_parse_resources, sc);
+   printf(" addr 0x%lx/0x%lx", sc->sc_addr, sc->sc_size);
+   if (sc->sc_addr == 0 || sc->sc_size == 0) {
+   printf("\n");
+   return;
+   }
+
+   printf(" irq %d", sc->sc_irq);
+
+   freq = acpi_getpropint(sc->sc_node, "clock-frequency", 0);
+
+   sc->sc.sc_iot = aaa->aaa_memt;
+   sc->sc.sc_iobase = sc->sc_addr;
+   sc->sc.sc_uarttype = COM_UART_16550;
+   sc->sc.sc_frequency = freq ? freq : COM_FREQ;
+
+   sc->sc.sc_reg_width = acpi_getpropint(sc->sc_node, "reg-io-width", 4);
+   sc->sc.sc_reg_shift = acpi_getpropint(sc->sc_node, "reg-shift", 2);
+
+   if (com_acpi_is_console(sc)) {
+   SET(sc->sc.sc_hwflags, COM_HW_CONSOLE);
+   SET(sc->sc.sc_swflags, COM_SW_SOFTCAR);
+   comconsfreq = sc->sc.sc_frequency;
+   comconsrate = B115200;
+   }
+
+   if (bus_space_map(sc->sc.sc_iot, sc->sc_addr, sc->sc_size, 0,
+   &sc->sc.sc_ioh)) {
+   printf(": can't map registers\n");
+   return;
+   }
+
+   sc->sc_ih = acpi_intr_establish(sc->sc_irq, sc->sc_irq_flags, IPL_TTY,
+   com_acpi_intr_designware, sc, sc->sc.sc_dev.dv_xname);
+   if (sc->sc_ih == NULL) {
+   printf(": can't establish interrupt\n");
+   return;
+   }
+
+   com_attach_subr(&sc->sc);
+}
+
+int
+com_acpi_parse_resources(int crsidx, union acpi_resource *crs, void *arg)
+{
+   struct com_acpi_softc *sc = arg;
+   int type = AML_CRSTYPE(crs);
+
+   switch (type) {
+   case LR_MEM32FIXED:
+   sc->sc_addr = crs->lr_m32fixed._bas;
+   sc->sc_size = crs->lr_m32fixed._len;
+   break;
+   case

Another acpidump(4) fix

2018-06-30 Thread Mark Kettenis
The pointer to the DSDT may be 64-bit as well.  In that case the
32-bit field will be zero and we have to use the 64-bit field.

ok?


Index: acpidump.c
===
RCS file: /cvs/src/usr.sbin/acpidump/acpidump.c,v
retrieving revision 1.18
diff -u -p -r1.18 acpidump.c
--- acpidump.c  24 Jun 2018 10:39:59 -  1.18
+++ acpidump.c  30 Jun 2018 18:41:51 -
@@ -532,7 +532,10 @@ acpi_handle_facp(struct FACPbody *facp)
struct ACPIsdt  *dsdp;
 
acpi_print_facp(facp);
-   dsdp = (struct ACPIsdt *) acpi_map_sdt(facp->dsdt_ptr);
+   if (facp->dsdt_ptr == 0)
+   dsdp = (struct ACPIsdt *) acpi_map_sdt(facp->x_dsdt);
+   else
+   dsdp = (struct ACPIsdt *) acpi_map_sdt(facp->dsdt_ptr);
if (acpi_checksum(dsdp, dsdp->len))
errx(1, "DSDT is corrupt");
acpi_handle_dsdt(dsdp);



ahci@acpi

2018-07-01 Thread Mark Kettenis
Diff below makes it possible to attach ahci(4) at acpi(4) as required by
arm64 machines like the MACCHIATOBin and Overdrive 1000.

ok?


Index: dev/acpi/ahci_acpi.c
===
RCS file: dev/acpi/ahci_acpi.c
diff -N dev/acpi/ahci_acpi.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ dev/acpi/ahci_acpi.c1 Jul 2018 12:13:03 -
@@ -0,0 +1,145 @@
+/* $OpenBSD$   */
+/*
+ * Copyright (c) 2018 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#undef DEVNAME
+#include 
+#include 
+
+struct ahci_acpi_softc {
+   struct ahci_softc sc;
+   struct acpi_softc *sc_acpi;
+   struct aml_node *sc_node;
+
+   bus_addr_t sc_addr;
+   bus_size_t sc_size;
+
+   int sc_irq;
+   int sc_irq_flags;
+   void *sc_ih;
+};
+
+intahci_acpi_match(struct device *, void *, void *);
+void   ahci_acpi_attach(struct device *, struct device *, void *);
+
+struct cfattach ahci_acpi_ca = {
+   sizeof(struct ahci_acpi_softc), ahci_acpi_match, ahci_acpi_attach
+};
+
+const char *ahci_hids[] = {
+   "AMDI0600",
+   "LNRO001E",
+   NULL
+};
+
+intahci_acpi_parse_resources(int, union acpi_resource *, void *);
+
+int
+ahci_acpi_match(struct device *parent, void *match, void *aux)
+{
+   struct acpi_attach_args *aaa = aux;
+   struct cfdata *cf = match;
+
+   return acpi_matchhids(aaa, ahci_hids, cf->cf_driver->cd_name);
+}
+
+void
+ahci_acpi_attach(struct device *parent, struct device *self, void *aux)
+{
+   struct acpi_attach_args *aaa = aux;
+   struct ahci_acpi_softc *sc = (struct ahci_acpi_softc *)self;
+   struct aml_value res;
+
+   sc->sc_acpi = (struct acpi_softc *)parent;
+   sc->sc_node = aaa->aaa_node;
+   printf(" %s", sc->sc_node->name);
+
+   if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) {
+   printf(": can't find registers\n");
+   return;
+   }
+
+   aml_parse_resource(&res, ahci_acpi_parse_resources, sc);
+   printf(" addr 0x%lx/0x%lx", sc->sc_addr, sc->sc_size);
+   if (sc->sc_addr == 0 || sc->sc_size == 0) {
+   printf("\n");
+   return;
+   }
+
+   printf(" irq %d", sc->sc_irq);
+
+   sc->sc.sc_iot = aaa->aaa_memt;
+   sc->sc.sc_ios = sc->sc_size;
+   sc->sc.sc_dmat = aaa->aaa_dmat;
+
+   if (bus_space_map(sc->sc.sc_iot, sc->sc_addr, sc->sc_size, 0,
+   &sc->sc.sc_ioh)) {
+   printf(": can't map registers\n");
+   return;
+   }
+
+   sc->sc_ih = acpi_intr_establish(sc->sc_irq, sc->sc_irq_flags, IPL_BIO,
+   ahci_intr, sc, sc->sc.sc_dev.dv_xname);
+   if (sc->sc_ih == NULL) {
+   printf(": can't establish interrupt\n");
+   return;
+   }
+
+   printf(":");
+
+   if (ahci_attach(&sc->sc) != 0) {
+   /* error printed by ahci_attach */
+   goto irq;
+   }
+
+   return;
+
+irq:
+   return;
+}
+
+int
+ahci_acpi_parse_resources(int crsidx, union acpi_resource *crs, void *arg)
+{
+   struct ahci_acpi_softc *sc = arg;
+   int type = AML_CRSTYPE(crs);
+
+   switch (type) {
+   case LR_MEM32FIXED:
+   /* AHCI registers are specified by the first resource. */
+   if (sc->sc_size == 0) {
+   sc->sc_addr = crs->lr_m32fixed._bas;
+   sc->sc_size = crs->lr_m32fixed._len;
+   }
+   break;
+   case LR_EXTIRQ:
+   sc->sc_irq = crs->lr_extirq.irq[0];
+   sc->sc_irq_flags = crs->lr_extirq.flags;
+   break;
+   }
+
+   return 0;
+}
Index: dev/acpi/files.acpi
===
RCS file: /cvs/src/sys/dev/acpi/files.acpi,v
retrieving revision 1.45
diff -u -p -r1.45 files.acpi
--- dev/acpi/files.acpi 1

pluart@acpi

2018-07-01 Thread Mark Kettenis
Since the ARM SBSA Generic UART is effectively a PL011 UART, the
expectation is that most arm64 servers will actually have pluart(4) as
their serial console instead of com(4).  So we need a glue for
acpi(4).  This provides that glue and moves the shared code from
dev/fdt to dev/ic.

ok?

P.S. This driver needs some cleanup.  But that should be done separately.


Index: conf/files
===
RCS file: /cvs/src/sys/conf/files,v
retrieving revision 1.661
diff -u -p -r1.661 files
--- conf/files  20 Apr 2018 04:37:21 -  1.661
+++ conf/files  1 Jul 2018 14:29:40 -
@@ -324,6 +324,10 @@ device com: tty
 file   dev/ic/com.ccom & (com | com_cardbus | com_gsc |
   com_isapnp)  needs-flag
 
+# ARM PrimeCell PL011 UART
+device pluart: tty
+file   dev/ic/pluart.c pluart
+
 # PC-like keyboard controller
 define pckbcslot {[slot = -1]}
 device pckbc: pckbcslot
Index: dev/acpi/files.acpi
===
RCS file: /cvs/src/sys/dev/acpi/files.acpi,v
retrieving revision 1.45
diff -u -p -r1.45 files.acpi
--- dev/acpi/files.acpi 1 Jul 2018 10:29:30 -   1.45
+++ dev/acpi/files.acpi 1 Jul 2018 14:29:40 -
@@ -137,9 +137,17 @@ device ccpmic
 attach ccpmic at i2c
 file   dev/acpi/ccpmic.c   ccpmic
 
 # NS16550 compatible UART
 attach com at acpi with com_acpi
 file   dev/acpi/com_acpi.c com_acpi
+
+# PL011 UART
+attach pluart at acpi with pluart_acpi
+file   dev/acpi/pluart_acpi.c  pluart_acpi
 
 # SD Host Controller
 attach sdhc at acpi with sdhc_acpi
Index: dev/acpi/pluart_acpi.c
===
RCS file: dev/acpi/pluart_acpi.c
diff -N dev/acpi/pluart_acpi.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ dev/acpi/pluart_acpi.c  1 Jul 2018 14:29:40 -
@@ -0,0 +1,153 @@
+/* $OpenBSD$   */
+/*
+ * Copyright (c) 2018 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#undef DEVNAME
+#include 
+#include 
+
+struct pluart_acpi_softc {
+   struct pluart_softc sc;
+   struct acpi_softc *sc_acpi;
+   struct aml_node *sc_node;
+
+   bus_addr_t sc_addr;
+   bus_size_t sc_size;
+
+   int sc_irq;
+   int sc_irq_flags;
+   void *sc_ih;
+};
+
+intpluart_acpi_match(struct device *, void *, void *);
+void   pluart_acpi_attach(struct device *, struct device *, void *);
+
+struct cfattach pluart_acpi_ca = {
+   sizeof(struct pluart_acpi_softc), pluart_acpi_match, pluart_acpi_attach
+};
+
+const char *pluart_hids[] = {
+   "AMDI0511",
+   NULL
+};
+
+intpluart_acpi_parse_resources(int, union acpi_resource *, void *);
+intpluart_acpi_is_console(struct pluart_acpi_softc *);
+
+int
+pluart_acpi_match(struct device *parent, void *match, void *aux)
+{
+   struct acpi_attach_args *aaa = aux;
+   struct cfdata *cf = match;
+
+   return acpi_matchhids(aaa, pluart_hids, cf->cf_driver->cd_name);
+}
+
+void
+pluart_acpi_attach(struct device *parent, struct device *self, void *aux)
+{
+   struct acpi_attach_args *aaa = aux;
+   struct pluart_acpi_softc *sc = (struct pluart_acpi_softc *)self;
+   struct aml_value res;
+
+   sc->sc_acpi = (struct acpi_softc *)parent;
+   sc->sc_node = aaa->aaa_node;
+   printf(" %s", sc->sc_node->name);
+
+   if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) {
+   printf(": can't find registers\n");
+   return;
+   }
+
+   aml_parse_resource(&res, pluart_acpi_parse_resources, sc);
+   printf(" addr 0x%lx/0x%lx", sc->sc_addr, sc->sc_size);
+   if (sc->sc_addr == 0 || sc->sc_size == 0) {
+   printf("\n");
+   return;
+   }
+
+   printf(" irq %d", sc->sc_irq);
+
+   sc->sc.sc_iot = aaa->aaa_memt;
+   if (bus_space_map(sc->sc.sc_iot, sc->sc_addr, sc->sc_size, 0,
+   &a

acpi(4) attach glue for amd64/i386

2018-07-01 Thread Mark Kettenis
Diff below moves the attach glue from acpi.c into acpi_machdep.c.
Gets rid of an #ifdef and helps me avoid an ugly hack on arm64.  There
is some additional code duplication, but I think this is acceptable.

ok?


Index: arch/amd64/amd64/acpi_machdep.c
===
RCS file: /cvs/src/sys/arch/amd64/amd64/acpi_machdep.c,v
retrieving revision 1.82
diff -u -p -r1.82 acpi_machdep.c
--- arch/amd64/amd64/acpi_machdep.c 25 Jun 2018 22:33:24 -  1.82
+++ arch/amd64/amd64/acpi_machdep.c 1 Jul 2018 14:56:50 -
@@ -32,11 +32,12 @@
 
 #include 
 
-#include 
 #include 
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include "isa.h"
 #include "ioapic.h"
@@ -63,6 +64,42 @@ extern int acpi_savecpu(void) __returns_
 #define ACPI_BIOS_RSDP_WINDOW_SIZE0x2
 
 u_int8_t   *acpi_scan(struct acpi_mem_map *, paddr_t, size_t);
+
+intacpi_match(struct device *, void *, void *);
+void   acpi_attach(struct device *, struct device *, void *);
+
+struct cfattach acpi_ca = {
+   sizeof(struct acpi_softc), acpi_match, acpi_attach
+};
+
+int
+acpi_match(struct device *parent, void *match, void *aux)
+{
+   struct bios_attach_args *ba = aux;
+   struct cfdata   *cf = match;
+
+   /* sanity */
+   if (strcmp(ba->ba_name, cf->cf_driver->cd_name))
+   return (0);
+
+   if (!acpi_probe(parent, cf, ba))
+   return (0);
+
+   return (1);
+}
+
+void
+acpi_attach(struct device *parent, struct device *self, void *aux)
+{
+   struct acpi_softc *sc = (struct acpi_softc *)self;
+   struct bios_attach_args *ba = aux;
+
+   sc->sc_iot = ba->ba_iot;
+   sc->sc_memt = ba->ba_memt;
+   sc->sc_dmat = &pci_bus_dma_tag;
+
+   acpi_attach_common(sc, ba->ba_acpipbase);
+}
 
 int
 acpi_map(paddr_t pa, size_t len, struct acpi_mem_map *handle)
Index: arch/amd64/conf/files.amd64
===
RCS file: /cvs/src/sys/arch/amd64/conf/files.amd64,v
retrieving revision 1.95
diff -u -p -r1.95 files.amd64
--- arch/amd64/conf/files.amd64 25 Jan 2018 15:06:29 -  1.95
+++ arch/amd64/conf/files.amd64 1 Jul 2018 14:56:50 -
@@ -232,6 +232,7 @@ include "dev/gpio/files.gpio"
 # ACPI
 #
 include "dev/acpi/files.acpi"
+attach acpi at bios
 file   arch/amd64/amd64/acpi_machdep.c acpi
 file   arch/amd64/amd64/acpi_wakecode.Sacpi & !small_kernel
 
Index: arch/i386/conf/files.i386
===
RCS file: /cvs/src/sys/arch/i386/conf/files.i386,v
retrieving revision 1.237
diff -u -p -r1.237 files.i386
--- arch/i386/conf/files.i386   25 Jan 2018 15:06:29 -  1.237
+++ arch/i386/conf/files.i386   1 Jul 2018 14:56:50 -
@@ -389,6 +389,7 @@ include "dev/onewire/files.onewire"
 include "dev/sdmmc/files.sdmmc"
 
 include "dev/acpi/files.acpi"
+attach acpi at bios
 file   arch/i386/i386/acpi_machdep.c   acpi
 file   arch/i386/i386/acpi_wakecode.S  acpi & !small_kernel
 
Index: arch/i386/i386/acpi_machdep.c
===
RCS file: /cvs/src/sys/arch/i386/i386/acpi_machdep.c,v
retrieving revision 1.66
diff -u -p -r1.66 acpi_machdep.c
--- arch/i386/i386/acpi_machdep.c   25 Jun 2018 22:33:24 -  1.66
+++ arch/i386/i386/acpi_machdep.c   1 Jul 2018 14:56:50 -
@@ -39,10 +39,11 @@
 #include 
 #include 
 
-#include 
 #include 
 #include 
 #include 
+#include 
+#include 
 
 #include "apm.h"
 #include "isa.h"
@@ -73,6 +74,42 @@ extern void intr_calculatemasks(void);
 #define ACPI_BIOS_RSDP_WINDOW_SIZE0x2
 
 u_int8_t   *acpi_scan(struct acpi_mem_map *, paddr_t, size_t);
+
+intacpi_match(struct device *, void *, void *);
+void   acpi_attach(struct device *, struct device *, void *);
+
+struct cfattach acpi_ca = {
+   sizeof(struct acpi_softc), acpi_match, acpi_attach
+};
+
+int
+acpi_match(struct device *parent, void *match, void *aux)
+{
+   struct bios_attach_args *ba = aux;
+   struct cfdata   *cf = match;
+
+   /* sanity */
+   if (strcmp(ba->ba_name, cf->cf_driver->cd_name))
+   return (0);
+
+   if (!acpi_probe(parent, cf, ba))
+   return (0);
+
+   return (1);
+}
+
+void
+acpi_attach(struct device *parent, struct device *self, void *aux)
+{
+   struct acpi_softc *sc = (struct acpi_softc *)self;
+   struct bios_attach_args *ba = aux;
+
+   sc->sc_iot = ba->ba_iot;
+   sc->sc_memt = ba->ba_memt;
+   sc->sc_dmat = &pci_bus_dma_tag;
+
+   acpi_attach_common(sc, ba->ba_acpipbase);
+}
 
 int
 acpi_map(paddr_t pa, size_t len, struct acpi_mem_map *handle)
Index: dev/acpi/acpi.c
===
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.351
diff -u -p -r1.351 acpi.c
--- dev/acpi/acpi.c 1 Jul 2018 10:27:34 -   1.3

arm64 acpi(4)

2018-07-01 Thread Mark Kettenis
Diff below actually enables acpi(4) on arm64.  Mostly stubs for bits of code 
that isn't needed on hardware-reduced ACPI.  But the functions have to be there 
for things to compile.

This is enough to boot my MACCHIATOBin multi-user.  A few more drivers
are coming, the crucial bit being pci(4) support.  At that point a
typical server system should mostly work.

ok?


Index: arch/arm64/arm64/acpi_machdep.c
===
RCS file: arch/arm64/arm64/acpi_machdep.c
diff -N arch/arm64/arm64/acpi_machdep.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ arch/arm64/arm64/acpi_machdep.c 1 Jul 2018 16:06:03 -
@@ -0,0 +1,190 @@
+/* $OpenBSD$   */
+/*
+ * Copyright (c) 2018 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+
+intlid_action;
+
+intacpi_fdt_match(struct device *, void *, void *);
+void   acpi_fdt_attach(struct device *, struct device *, void *);
+void   acpi_attach(struct device *, struct device *, void *);
+
+struct cfattach acpi_fdt_ca = {
+   sizeof(struct acpi_softc), acpi_fdt_match, acpi_fdt_attach
+};
+
+int
+acpi_fdt_match(struct device *parent, void *match, void *aux)
+{
+   struct fdt_attach_args *faa = aux;
+
+   return OF_is_compatible(faa->fa_node, "openbsd,acpi-5.0");
+}
+
+void
+acpi_fdt_attach(struct device *parent, struct device *self, void *aux)
+{
+   struct acpi_softc *sc = (struct acpi_softc *)self;
+   struct fdt_attach_args *faa = aux;
+   bus_dma_tag_t dmat;
+
+   /* Create coherent DMA tag. */
+   dmat = malloc(sizeof(*sc->sc_dmat), M_DEVBUF, M_WAITOK | M_ZERO);
+   memcpy(dmat, faa->fa_dmat, sizeof(*dmat));
+   dmat->_flags |= BUS_DMA_COHERENT;
+   
+   sc->sc_memt = faa->fa_iot;
+   sc->sc_dmat = dmat;
+
+   acpi_attach_common(sc, faa->fa_reg[0].addr);
+}
+
+int
+acpi_map(paddr_t pa, size_t len, struct acpi_mem_map *handle)
+{
+   paddr_t pgpa = trunc_page(pa);
+   paddr_t endpa = round_page(pa + len);
+   vaddr_t va = uvm_km_valloc(kernel_map, endpa - pgpa);
+
+   if (va == 0)
+   return (ENOMEM);
+
+   handle->baseva = va;
+   handle->va = (u_int8_t *)(va + (pa & PGOFSET));
+   handle->vsize = endpa - pgpa;
+   handle->pa = pa;
+
+   do {
+   pmap_kenter_pa(va, pgpa, PROT_READ | PROT_WRITE);
+   va += NBPG;
+   pgpa += NBPG;
+   } while (pgpa < endpa);
+
+   return 0;
+}
+
+void
+acpi_unmap(struct acpi_mem_map *handle)
+{
+   pmap_kremove(handle->baseva, handle->vsize);
+   uvm_km_free(kernel_map, handle->baseva, handle->vsize);
+}
+
+int
+acpi_bus_space_map(bus_space_tag_t t, bus_addr_t addr, bus_size_t size,
+int flags, bus_space_handle_t *bshp)
+{
+   return bus_space_map(t, addr, size, flags, bshp);
+}
+
+void
+acpi_bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh,
+bus_size_t size)
+{
+   bus_space_unmap(t, bsh, size);
+}
+
+int
+acpi_acquire_glk(uint32_t *lock)
+{
+   /* No global lock. */
+   return 1;
+}
+
+int
+acpi_release_glk(uint32_t *lock)
+{
+   /* No global lock. */
+   return 0;
+}
+
+void
+acpi_attach_machdep(struct acpi_softc *sc)
+{
+   /* Nothing to do. */
+}
+
+void *
+acpi_intr_establish(int irq, int flags, int level,
+int (*func)(void *), void *arg, const char *name)
+{
+   struct interrupt_controller *ic;
+   uint32_t interrupt[3];
+
+   extern LIST_HEAD(, interrupt_controller) interrupt_controllers;
+   LIST_FOREACH(ic, &interrupt_controllers, ic_list) {
+   if (ic->ic_phandle == 1)
+   break;
+   }
+   if (ic == NULL)
+   return NULL;
+
+   interrupt[0] = 0;
+   interrupt[1] = irq - 32;
+   interrupt[2] = 0x4;
+
+   return ic->ic_establish(ic->ic_cookie, interrupt, level,
+   func, arg, (char *)name);
+}
+
+void
+acpi_sleep_clocks(struct acpi_softc *sc, int state)
+{
+}
+
+void
+acpi_resume_clocks(struct acpi_softc *sc)
+{
+}
+
+int
+acpi_sleep_cpu(struct 

xhci@acpi

2018-07-02 Thread Mark Kettenis
Totally straightforward.

ok?


Index: arch/arm64/conf/GENERIC
===
RCS file: /cvs/src/sys/arch/arm64/conf/GENERIC,v
retrieving revision 1.74
diff -u -p -r1.74 GENERIC
--- arch/arm64/conf/GENERIC 1 Jul 2018 19:30:37 -   1.74
+++ arch/arm64/conf/GENERIC 2 Jul 2018 09:35:47 -
@@ -42,6 +42,7 @@ acpibtn*  at acpi?
 acpiec*at acpi?
 ahci*  at acpi?
 com*   at acpi?
+xhci*  at acpi?
 simplebus* at fdt?
 
 scsibus*   at scsi?
Index: arch/arm64/conf/RAMDISK
===
RCS file: /cvs/src/sys/arch/arm64/conf/RAMDISK,v
retrieving revision 1.61
diff -u -p -r1.61 RAMDISK
--- arch/arm64/conf/RAMDISK 1 Jul 2018 19:30:37 -   1.61
+++ arch/arm64/conf/RAMDISK 2 Jul 2018 09:35:47 -
@@ -52,6 +52,7 @@ acpi0 at mainbus?
 acpiec*at acpi?
 ahci*  at acpi?
 com*   at acpi?
+xhci*  at acpi?
 simplebus* at fdt?
 
 scsibus*   at scsi?
Index: dev/acpi/files.acpi
===
RCS file: /cvs/src/sys/dev/acpi/files.acpi,v
retrieving revision 1.47
diff -u -p -r1.47 files.acpi
--- dev/acpi/files.acpi 1 Jul 2018 15:54:59 -   1.47
+++ dev/acpi/files.acpi 2 Jul 2018 09:35:48 -
@@ -148,6 +148,10 @@ file   dev/acpi/com_acpi.c com_acpi
 attach sdhc at acpi with sdhc_acpi
 file   dev/acpi/sdhc_acpi.csdhc_acpi
 
+# XHCI
+attach xhci at acpi with xhci_acpi
+file   dev/acpi/xhci_acpi.cxhci_acpi
+
 # Synopsys DesignWare I2C controller
 attach dwiic at acpi with dwiic_acpi
 file   dev/acpi/dwiic_acpi.c   dwiic_acpi
Index: dev/acpi/xhci_acpi.c
===
RCS file: dev/acpi/xhci_acpi.c
diff -N dev/acpi/xhci_acpi.c
--- /dev/null   1 Jan 1970 00:00:00 -
+++ dev/acpi/xhci_acpi.c2 Jul 2018 09:35:48 -
@@ -0,0 +1,163 @@
+/* $OpenBSD$   */
+/*
+ * Copyright (c) 2018 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+struct xhci_acpi_softc {
+   struct xhci_softc sc;
+   struct acpi_softc *sc_acpi;
+   struct aml_node *sc_node;
+
+   bus_addr_t  sc_addr;
+   bus_size_t  sc_size;
+
+   int sc_irq;
+   int sc_irq_flags;
+   void*sc_ih;
+};
+
+intxhci_acpi_match(struct device *, void *, void *);
+void   xhci_acpi_attach(struct device *, struct device *, void *);
+
+struct cfattach xhci_acpi_ca = {
+   sizeof(struct xhci_acpi_softc), xhci_acpi_match, xhci_acpi_attach
+};
+
+const char *xhci_hids[] = {
+   "PNP0D10",
+   NULL
+};
+
+intxhci_acpi_parse_resources(int, union acpi_resource *, void *);
+
+int
+xhci_acpi_match(struct device *parent, void *match, void *aux)
+{
+   struct acpi_attach_args *aaa = aux;
+   struct cfdata *cf = match;
+
+   return acpi_matchhids(aaa, xhci_hids, cf->cf_driver->cd_name);
+}
+
+void
+xhci_acpi_attach(struct device *parent, struct device *self, void *aux)
+{
+   struct xhci_acpi_softc *sc = (struct xhci_acpi_softc *)self;
+   struct acpi_attach_args *aaa = aux;
+   struct aml_value res;
+   int error;
+
+   sc->sc_acpi = (struct acpi_softc *)parent;
+   sc->sc_node = aaa->aaa_node;
+   printf(" %s", sc->sc_node->name);
+
+   if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) {
+   printf(": can't find registers\n");
+   return;
+   }
+
+   aml_parse_resource(&res, xhci_acpi_parse_resources, sc);
+   printf(" addr 0x%lx/0x%lx", sc->sc_addr, sc->sc_size);
+   if (sc->sc_addr == 0 || sc->sc_size == 0) {
+   printf("\n");
+   return;
+   }
+
+   printf(" irq %d", sc->sc_irq);
+
+   sc->sc.iot = aaa->aaa_memt;
+   sc

Re: xhci@acpi

2018-07-02 Thread Mark Kettenis
> Date: Mon, 2 Jul 2018 08:31:23 -0700
> From: Mike Larkin 
> 
> On Mon, Jul 02, 2018 at 11:36:59AM +0200, Mark Kettenis wrote:
> > Totally straightforward.
> > 
> > ok?
> > 
> >
> 
> ok mlarkin
> 
> Just wondering if you need to update the man pages for ahci(4)
> and xhci(4) to include the "at acpi0" attachments?

good point!

> > Index: arch/arm64/conf/GENERIC
> > ===
> > RCS file: /cvs/src/sys/arch/arm64/conf/GENERIC,v
> > retrieving revision 1.74
> > diff -u -p -r1.74 GENERIC
> > --- arch/arm64/conf/GENERIC 1 Jul 2018 19:30:37 -   1.74
> > +++ arch/arm64/conf/GENERIC 2 Jul 2018 09:35:47 -
> > @@ -42,6 +42,7 @@ acpibtn*  at acpi?
> >  acpiec*at acpi?
> >  ahci*  at acpi?
> >  com*   at acpi?
> > +xhci*  at acpi?
> >  simplebus* at fdt?
> >  
> >  scsibus*   at scsi?
> > Index: arch/arm64/conf/RAMDISK
> > ===
> > RCS file: /cvs/src/sys/arch/arm64/conf/RAMDISK,v
> > retrieving revision 1.61
> > diff -u -p -r1.61 RAMDISK
> > --- arch/arm64/conf/RAMDISK 1 Jul 2018 19:30:37 -   1.61
> > +++ arch/arm64/conf/RAMDISK 2 Jul 2018 09:35:47 -
> > @@ -52,6 +52,7 @@ acpi0 at mainbus?
> >  acpiec*at acpi?
> >  ahci*  at acpi?
> >  com*   at acpi?
> > +xhci*  at acpi?
> >  simplebus* at fdt?
> >  
> >  scsibus*   at scsi?
> > Index: dev/acpi/files.acpi
> > ===
> > RCS file: /cvs/src/sys/dev/acpi/files.acpi,v
> > retrieving revision 1.47
> > diff -u -p -r1.47 files.acpi
> > --- dev/acpi/files.acpi 1 Jul 2018 15:54:59 -   1.47
> > +++ dev/acpi/files.acpi 2 Jul 2018 09:35:48 -
> > @@ -148,6 +148,10 @@ file   dev/acpi/com_acpi.c com_acpi
> >  attach sdhc at acpi with sdhc_acpi
> >  file   dev/acpi/sdhc_acpi.csdhc_acpi
> >  
> > +# XHCI
> > +attach xhci at acpi with xhci_acpi
> > +file   dev/acpi/xhci_acpi.cxhci_acpi
> > +
> >  # Synopsys DesignWare I2C controller
> >  attach dwiic at acpi with dwiic_acpi
> >  file   dev/acpi/dwiic_acpi.c   dwiic_acpi
> > Index: dev/acpi/xhci_acpi.c
> > ===
> > RCS file: dev/acpi/xhci_acpi.c
> > diff -N dev/acpi/xhci_acpi.c
> > --- /dev/null   1 Jan 1970 00:00:00 -
> > +++ dev/acpi/xhci_acpi.c2 Jul 2018 09:35:48 -
> > @@ -0,0 +1,163 @@
> > +/* $OpenBSD$   */
> > +/*
> > + * Copyright (c) 2018 Mark Kettenis
> > + *
> > + * Permission to use, copy, modify, and distribute this software for any
> > + * purpose with or without fee is hereby granted, provided that the above
> > + * copyright notice and this permission notice appear in all copies.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include 
> > +#include 
> > +
> > +struct xhci_acpi_softc {
> > +   struct xhci_softc sc;
> > +   struct acpi_softc *sc_acpi;
> > +   struct aml_node *sc_node;
> > +
> > +   bus_addr_t  sc_addr;
> > +   bus_size_t  sc_size;
> > +
> > +   int sc_irq;
> > +   int sc_irq_flags;
> > +   void*sc_ih;
> > +};
> > +
> > +intxhci_acpi_match(struct device *, void *, void *);
> > +void   xhci_acpi_attach(struct device *, struct device *, void *);
> > +
> > +struct cfattach xhci_acpi_ca = {
> > +   si

<    7   8   9   10   11   12   13   14   15   16   >