diff -Nru /sys/src/9/bcm/archbcm2.c /sys/src/9/bcm/archbcm2.c --- /sys/src/9/bcm/archbcm2.c Fri Mar 4 00:00:00 2016 +++ /sys/src/9/bcm/archbcm2.c Tue Mar 22 00:00:00 2016 @@ -18,7 +18,6 @@ typedef struct Mboxes Mboxes; #define POWERREGS (VIRTIO+0x100000) -#define ARMLOCAL (VIRTIO+IOSIZE) Soc soc = { .dramsize = 0x3F000000, /* was 1024*MiB, but overlaps with physio */ diff -Nru /sys/src/9/bcm/clock.c /sys/src/9/bcm/clock.c --- /sys/src/9/bcm/clock.c Fri Mar 4 00:00:00 2016 +++ /sys/src/9/bcm/clock.c Tue Mar 22 00:00:00 2016 @@ -25,7 +25,6 @@ enum { SYSTIMERS = VIRTIO+0x3000, ARMTIMER = VIRTIO+0xB400, - ARMLOCAL = (VIRTIO+IOSIZE), Localctl = 0x00, Prescaler = 0x08, diff -Nru /sys/src/9/bcm/fns.h /sys/src/9/bcm/fns.h --- /sys/src/9/bcm/fns.h Fri Mar 4 00:00:00 2016 +++ /sys/src/9/bcm/fns.h Tue Mar 22 00:00:00 2016 @@ -97,6 +97,8 @@ extern void uartconsinit(void); extern int userureg(Ureg*); extern void vectors(void); +extern void vgpinit(void); +extern void vgpset(uint, int); extern void vtable(void); extern void wdogoff(void); extern void wdogfeed(void); diff -Nru /sys/src/9/bcm/fpiarm.c /sys/src/9/bcm/fpiarm.c --- /sys/src/9/bcm/fpiarm.c Mon Mar 25 00:00:00 2013 +++ /sys/src/9/bcm/fpiarm.c Tue Mar 22 00:00:00 2016 @@ -220,6 +220,7 @@ { void *mem; + validaddr(ea, n, 0); mem = (void*)ea; (*f)(&FR(ufp, d), mem); if(fpemudebug) @@ -232,6 +233,7 @@ Internal tmp; void *mem; + validaddr(ea, n, 1); mem = (void*)ea; tmp = FR(ufp, s); if(fpemudebug) diff -Nru /sys/src/9/bcm/main.c /sys/src/9/bcm/main.c --- /sys/src/9/bcm/main.c Tue Mar 22 00:00:00 2016 +++ /sys/src/9/bcm/main.c Tue Mar 22 00:00:00 2016 @@ -331,6 +331,7 @@ swcursorinit(); cpuidprint(); archreset(); + vgpinit(); procinit0(); initseg(); diff -Nru /sys/src/9/bcm/mem.h /sys/src/9/bcm/mem.h --- /sys/src/9/bcm/mem.h Thu Mar 3 00:00:00 2016 +++ /sys/src/9/bcm/mem.h Tue Mar 22 00:00:00 2016 @@ -47,6 +47,8 @@ #define L1 (KZERO+0x4000) /* tt ptes: 16KiB aligned */ #define KTZERO (KZERO+0x8000) /* kernel text start */ #define VIRTIO 0x7E000000 /* i/o registers */ +#define ARMLOCAL (VIRTIO+IOSIZE) /* armv7 only */ +#define VGPIO (ARMLOCAL+MiB) /* virtual gpio for pi3 ACT LED */ #define FRAMEBUFFER 0xC0000000 /* video framebuffer */ #define UZERO 0 /* user segment */ diff -Nru /sys/src/9/bcm/uartmini.c /sys/src/9/bcm/uartmini.c --- /sys/src/9/bcm/uartmini.c Sun Mar 6 00:00:00 2016 +++ /sys/src/9/bcm/uartmini.c Tue Mar 22 00:00:00 2016 @@ -445,13 +445,16 @@ if(p != nil) okled = strtol(p, 0, 0); else - return; + okled = 'v'; p = getconf("bcm2709.disk_led_active_low"); if(p == nil) p = getconf("bcm2708.disk_led_active_low"); polarity = (p == nil || *p == '1'); - gpiosel(okled, Output); + if(okled != 'v') + gpiosel(okled, Output); } - if(okled != 0) + if(okled == 'v') + vgpset(0, on); + else if(okled != 0) gpioout(okled, on^polarity); } diff -Nru /sys/src/9/bcm/vcore.c /sys/src/9/bcm/vcore.c --- /sys/src/9/bcm/vcore.c Fri Mar 27 00:00:00 2015 +++ /sys/src/9/bcm/vcore.c Tue Mar 22 00:00:00 2016 @@ -12,6 +12,7 @@ typedef struct Prophdr Prophdr; typedef struct Fbinfo Fbinfo; +typedef struct Vgpio Vgpio; enum { Read = 0x00>>2, @@ -52,8 +53,11 @@ TagSetvres = 0x00048004, TagGetdepth = 0x00040005, TagSetdepth = 0x00048005, - TagGetrgb = 0x00044006, + TagGetrgb = 0x00040006, TagSetrgb = 0x00048006, + TagGetGpio = 0x00040010, + + Nvgpio = 2, }; struct Fbinfo { @@ -79,6 +83,15 @@ u32int data[1]; }; +struct Vgpio { + u32int *counts; + u16int incs; + u16int decs; + int ison; +}; + +static Vgpio vgpio; + static void vcwrite(uint chan, int val) { @@ -338,4 +351,35 @@ if(vcreq(TagGettemp, buf, sizeof(buf[0]), sizeof buf) != sizeof buf) return 0; return buf[1]; +} + +/* + * Virtual GPIO - used for ACT LED on pi3 + */ +void +vgpinit(void) +{ + u32int buf[1]; + uintptr va; + + buf[0] = 0; + if(vcreq(TagGetGpio, buf, 0, sizeof(buf)) != sizeof buf || buf[0] == 0) + return; + va = mmukmap(VGPIO, buf[0] & ~0xC0000000, BY2PG); + if(va == 0) + return; + vgpio.counts = (u32int*)va; +} + +void +vgpset(uint port, int on) +{ + if(vgpio.counts == nil || port >= Nvgpio || on == vgpio.ison) + return; + if(on) + vgpio.incs++; + else + vgpio.decs++; + vgpio.counts[port] = (vgpio.incs << 16) | vgpio.decs; + vgpio.ison = on; }