/* ______ ___ ___ * /\ _ \ /\_ \ /\_ \ * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ * /\____/ * \_/__/ * * Memory mapping helpers for Linux Allegro. * * By George Foot, heavily based upon Marek Habersack's code. * * See readme.txt for copyright information. */ #ifndef _GNU_SOURCE #define _GNU_SOURCE #endif #include "allegro.h" #include "allegro/internal/aintern.h" #include "allegro/platform/aintunix.h" #if !defined(_POSIX_MAPPED_FILES) || !defined(HAVE_MMAP) #error "Sorry, mapped files are required for Linux console Allegro to work!" #endif #include #include static int mem_fd = -1; /* fd of /dev/mem */ /* __al_linux_init_memory: * Prepares to be able to map memory; returns 0 on success. */ int __al_linux_init_memory (void) { mem_fd = open ("/dev/mem", O_RDWR); if (mem_fd < 0) return 1; mprotect ((void *)&mem_fd, sizeof mem_fd, PROT_READ); return 0; } /* __al_linux_shutdown_memory: * Turns off memory mapping, returning 0 on success. */ int __al_linux_shutdown_memory (void) { if (mem_fd < 0) return 1; mprotect ((void *)&mem_fd, sizeof mem_fd, PROT_READ | PROT_WRITE); close (mem_fd); mem_fd = -1; return 0; } /* __al_linux_map_memory: * Given a MAPPED_MEMORY struct with physical address, size and * permissions filled in, this function maps the memory and fills * in the pointer in the struct. Returns 0 on success; errno will * be set on error. */ int __al_linux_map_memory (struct MAPPED_MEMORY *info) { ASSERT(info); info->data = mmap (0, info->size, info->perms, MAP_SHARED, mem_fd, info->base); if (info->data == MAP_FAILED) { info->data = NULL; return 1; } return 0; } /* __al_linux_unmap_memory: * Given a MAPPED_MEMORY struct, this function unmaps * the block. Returns 0 on success, errno set on error. */ int __al_linux_unmap_memory (struct MAPPED_MEMORY *info) { ASSERT(info); if (info->data == NULL) return 0; if (!munmap (info->data, info->size)) { info->data = NULL; return 0; } return 1; }