Bug 236373 - mmio doesn't work on mmio
Summary: mmio doesn't work on mmio
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: CURRENT
Hardware: arm Any
: --- Affects Only Me
Assignee: freebsd-arm (Nobody)
URL:
Keywords: needs-qa
Depends on:
Blocks:
 
Reported: 2019-03-07 18:43 UTC by Ralf Peglow
Modified: 2019-03-08 09:09 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ralf Peglow 2019-03-07 18:43:07 UTC
this test program should set all gpio pins to high level. it does, with different memory address, on raspbian. i guess there's something wrong with the port.

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>
#include <errno.h>
#include <stdint.h>

int main()
{
        volatile void *gpfs0; //general purpose function select 0
        int memfd;
        volatile uint32_t *gpfsr0; //general purpose function select register
		volatile uint32_t *gposr0; //general purpose output set register
		volatile uint32_t *gpocr0; //general purpose output clear register


        //open fd to physical memory
        memfd = open("/dev/mem", O_RDWR|O_SYNC);
        if(memfd == -1)
        {
                printf("error opening /dev/mem\n");
                return 1;
        }

        //mapping into memory
        gpfs0 = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_SHARED, memfd, 0x7e200000);
        if(gpfs0 == MAP_FAILED)
        {
                printf("map failed: %d\n", errno);
                return 1;
        }	

        gpfsr0 = gpfs0; //GPIO Function select 0		
				
       gposr0 = gpfs0 + 0x1c; //GPIO Output Set 0
		//gposr1 = gpfs0 + 32; //GPIO Output Set 0
		
        gpocr0 = gpfs0 + 0x28; //GPIO Output Clear 0
	//	gpocr1 = gpfs0 + 44; //GPIO Output Clear 0
		
		*gpfsr0 = 0111111111;
		
		*gposr0 = 0xffffffff;

		munmap((void *) gpfs0, sysconf(_SC_PAGE_SIZE));

		//printf("%ld\n", sysconf(_SC_PAGE_SIZE));

		printf("finish\n");

        return 0;
}
Comment 1 Kubilay Kocak freebsd_committer freebsd_triage 2019-03-08 04:41:14 UTC
@Ralf What is the exact version (uname -a) of the system, and could you clarify what the specific "observed" and "expected" behaviours and outputs are for the code in question?
Comment 2 Ralf Peglow 2019-03-08 09:09:44 UTC
the version is FreeBSD generic 12.0-RELEASE FreeBSD 12.0-RELEASE r341666 GENERIC  arm64, the "RELEASE RPI2" and "RELEASE RPI3", but it doesn't work with the "CURRENT RPI2" and the "CURRENT RPI3 from the homepage, too.

the expected behaviour would be a glowing led connected to GPIO2 (pin no 3) and GPIO5 (pin no 29) or 3 volts dc to ground at these pins.

the observed behaviour is a light glowing led at GPIO2 and a not glowing led at GPIO5.

by the way this program freezes after a few rounds:

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>
#include <errno.h>
#include <stdint.h>

int main()
{
        volatile void *gpfs0; //general purpose function select 0
        int memfd;
        volatile uint32_t *gpfsr0; //general purpose function select register
		volatile uint32_t *gposr0; //general purpose output set register
		volatile uint32_t *gpocr0; //general purpose output clear register


        //open fd to physical memory
        memfd = open("/dev/mem", O_RDWR|O_SYNC);
        if(memfd == -1)
        {
                printf("error opening /dev/mem\n");
                return 1;
        }

        //mapping into memory
        gpfs0 = mmap(NULL, sysconf(_SC_PAGE_SIZE), PROT_READ | PROT_WRITE, MAP_SHARED, memfd, 0x7e200000);
        if(gpfs0 == MAP_FAILED)
        {
                printf("map failed: %d\n", errno);
                return 1;
        }	

        gpfsr0 = gpfs0; //GPIO Function select 0		
				
       gposr0 = gpfs0 + 0x1c; //GPIO Output Set 0
		
        gpocr0 = gpfs0 + 0x28; //GPIO Output Clear 0
		
		*gpfsr0 = 0111111111;
for(;;)
{	
printf("on\n");
		*gposr0 = 0xffffffff;
		usleep(1000000);
		printf("off\n");
		*gpocr0 = 0xffffffff;
		usleep(1000000);
}

		munmap((void *) gpfs0, sysconf(_SC_PAGE_SIZE));

		printf("finish\n");

        return 0;
}