/* * poke.c - Read or write any CPU register * * Copyright (C) 2008 by OpenMoko, Inc. * Written by Werner Almesberger * All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. */ #include #include #include #include #include #include #define PAGE_SIZE 4096 #define MEM(bits, addr) (*(uint##bits##_t *) (mem+((addr) & (PAGE_SIZE-1)))) static volatile void *mem; /* ----- Command-line parsing ---------------------------------------------- */ static void __attribute__((noreturn)) usage(const char *name) { fprintf(stderr, "usage: %s [-8|-16|-32] hex_address [value]\n", name); exit(1); } int main(int argc, char **argv) { int fd; char *end; unsigned long addr; uint32_t val; int bits = 32; char **args = argv+1; fd = open("/dev/mem", O_RDWR); if (fd < 0) { perror("/dev/mem"); exit(1); } if (argc > 1 && *argv[1] == '-') { if (!strcmp(argv[1], "-8")) bits = 8; else if (!strcmp(argv[1], "-16")) bits = 16; else if (!strcmp(argv[1], "-32")) bits = 32; else usage(*argv); args++; argc--; /* dirty */ } switch (argc) { case 3: val = strtoul(args[1], &end, 0); if (*end) usage(*argv); /* fall through */ case 2: addr = strtoul(args[0], &end, 16); if (*end) usage(*argv); break; default: usage(*argv); } mem = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr & ~(PAGE_SIZE-1)); if (mem == MAP_FAILED) { perror("mmap"); exit(1); } if (argc == 2) { switch (bits) { case 8: printf("0x%02lx\n", (unsigned long) MEM(8, addr)); break; case 16: printf("0x%04lx\n", (unsigned long) MEM(16, addr)); break; case 32: printf("0x%08lx\n", (unsigned long) MEM(32, addr)); break; } } else { switch (bits) { case 8: MEM(8, addr) = val; break; case 16: MEM(16, addr) = val; break; case 32: MEM(32, addr) = val; break; } } return 0; }