All pastes #424701 Raw Edit

Someone

public text v1 · immutable
·published 2007-04-04 23:08 UTC
rendered paste body
#include <stdio.h>
#include <stdlib.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>

#ifdef __PPC__
extern inline void out_8(volatile unsigned char *addr, unsigned val)
{
        __asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
}
/* etc., cf asm/io.h */
#else
extern inline void out_8(volatile unsigned char *addr, unsigned val)
{
        *addr = val & 0xff;
}
#endif


volatile void * ioremap(unsigned long physaddr, unsigned size)
{
    static int axs_mem_fd = -1;
    unsigned long page_addr, ofs_addr, reg, pgmask;
    void* reg_mem = NULL;

    /*
     * looks like mmap wants aligned addresses?
     */
    pgmask = getpagesize()-1;
    page_addr = physaddr & ~pgmask;
    ofs_addr  = physaddr & pgmask;

    /*
     * Don't forget O_SYNC, esp. if address is in RAM region.
     * Note: if you do know you'll access in Read Only mode,
     *    pass O_RDONLY to open, and PROT_READ only to mmap
     */
    if (axs_mem_fd == -1) {
        axs_mem_fd = open("/dev/mem", O_RDWR|O_SYNC);
        if (axs_mem_fd < 0) {
                perror("AXS: can't open /dev/mem");
                return NULL;
        }
    }

    /* memory map */
    reg_mem = mmap(
        (caddr_t)reg_mem,
        size+ofs_addr,
        PROT_READ|PROT_WRITE,
        MAP_SHARED,
        axs_mem_fd,
        page_addr
    );
    if (reg_mem == MAP_FAILED) {
        perror("AXS: mmap error");
        close(axs_mem_fd);
        return NULL;
    }

    reg = (unsigned long )reg_mem + ofs_addr;
    return (volatile void *)reg;
}

int iounmap(volatile void *start, size_t length)
{
    unsigned long ofs_addr;
    ofs_addr = (unsigned long)start & (getpagesize()-1);

    /* do some cleanup when you're done with it */
    return munmap((unsigned char*)start-ofs_addr, length+ofs_addr);
}

int main(int argc, char **argv)
{
        volatile unsigned int *gfx = ioremap(0xec806000, 0x1000);

        int vxres = gfx[0x134/4];
        int vyres = gfx[0x138/4];

        int scl_h = gfx[0x5b4/4], scl_v = gfx[0x5c4/4];

        int black_top = gfx[0x44/4];

        printf("virtual resolution: %d x %d\n", vxres, vyres);
        printf("scaling factors: %f x %f\n", scl_h / (float)0x1000000, scl_v / (float)0x1000000);

        printf("black: %d %d, %d %d\n",
                gfx[0x44/4], gfx[0x48/4], gfx[0x4c/4], gfx[0x50/4]);

        printf("native resolution: %d x %d\n",
                vxres * 0x1000 / (scl_h/0x1000),
                vyres * 0x1000 / (scl_v/0x1000) + black_top * 2);
}