Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / dummy_mods / iob / iob.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: iob.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
//
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
//
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
// ========== Copyright Header End ============================================
/* iob.C
* handle IOB (I/O space) T1 addresses for blaze/SAM
*
* Copyright (c) 2004 by Sun Microsystems, Inc.
* All rights reserved.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/syscall.h> // get exec number
#include <sys/types.h> // uid_t
#include <unistd.h> // getuid()
#include <inttypes.h>
#include <stdarg.h>
#include <thread.h>
#include "mmi.h"
#include "ui.h"
struct sam_iob_s {
uint64_t startpa;
uint64_t endpa;
uint64_t sz;
}; // struct sam_iob.C
extern "C" int iob_access(uint32_t cpuid, void* obj, uint64_t paddr, mmi_bool_t wr, uint32_t size, uint64_t* buf, uint8_t bytemask);
int iob_ld_operation (void *cd, uint64_t paddr, uint64_t *buf, int sz, uint32_t cpuid);
int iob_st_operation (void *cd, uint64_t paddr, uint64_t *buf, int sz, uint32_t cpuid);
extern "C" void iob_create_instance (const char *modname, const char *instance_name);
extern "C" void _init()
{
if (! mmi_register_instance_creator("iob", iob_create_instance) ) {
fprintf(stderr, "Cannot register instance creator for iob\n");
}
} // _init()
void iob_create_instance (const char *modname, const char *instance_name)
{
sam_iob_s * iob_obj = new sam_iob_s;
mmi_instance_t instance = mmi_register_instance(modname, instance_name, (void *) &iob_obj, "iob dummy device");
iob_obj->startpa = 0x0;
iob_obj->endpa = 0x0;
iob_obj->sz = 0;
// expected syntax: sysconf iob iob1 startpa=<0xblah> endpa=<0xblah>
int argc = mmi_argc(instance);
int i;
for (i=0; i<argc; i++) {
char * arg = strdup(mmi_argv(instance, i));
char * marker;
char * lv = strtok_r(arg, "=", &marker);
if (strcmp(lv, "startpa") == 0) {
errno = 0;
char * rv = strtok_r(NULL, "=", &marker);
iob_obj->startpa = strtoull(rv, NULL, 0);
if (errno) {
perror("iob: error parsing startpa");
exit(1);
}
} else if (strcmp(lv, "endpa") == 0) {
errno = 0;
char * rv = strtok_r(NULL, "=", &marker);
iob_obj->endpa = strtoull(rv, NULL, 0);
if (errno) {
perror("iob: error parsing startpa");
exit(1);
}
} // else - do nothing
}
iob_obj->sz = iob_obj->endpa - iob_obj->startpa + 1;
if (mmi_map_physio(iob_obj->startpa, iob_obj->sz, (void *) iob_obj, iob_access)) {
fprintf(stderr, " sam iob: unable to register IO interceptor\n");
return;
}
}
int iob_access(uint32_t cpuid, void* obj, uint64_t paddr, mmi_bool_t wr, uint32_t size, uint64_t* buf, uint8_t bytemask)
{
if (wr) {
return iob_st_operation(obj, paddr, buf, size, cpuid);
} else {
return iob_ld_operation(obj, paddr, buf, size, cpuid);
}
} // iob_access()
int iob_ld_operation (void *obj, uint64_t paddr, uint64_t *buf, int size, uint32_t cpuid)
{
sam_iob_s * iob_obj = (sam_iob_s *) obj;
uint64_t offset = paddr - iob_obj->startpa;
// fprintf(stderr, "SAM iob: ld_operation pa 0x%llx size %d cpu %d\n", paddr, size, cpuid);
switch (offset) {
case 0x0:
*buf = 0;
break;
default:
*buf = 0;
break;
// fprintf(stderr, "SAM iob: ld from invalid paddr 0x%llx\n", paddr);
// exit(1);
}
return 0;
} // int iob_ld_operation (void *cd, uint64_t paddr, uint64_t *buf, int size, uint32_t cpuid)
int iob_st_operation (void *obj, uint64_t paddr, uint64_t *buf, int size, uint32_t cpuid)
{
// fprintf(stderr, "SAM iob: st_operation pa 0x%llx size %d cpu %d\n", paddr, size, cpuid);
sam_iob_s * iob_obj = (sam_iob_s *) obj;
uint64_t offset = paddr - iob_obj->startpa;
switch (offset) {
case 0x800: // case 0x9800000800:
// do nothing
break;
case 0xa00:
break;
default:
fprintf(stderr, "SAM iob: st to invalid paddr 0x%llx\n", paddr);
exit(1);
}
return 0;
} // int iob_st_operation (void *cd, uint64_t paddr, uint64_t *buf, int size, uint32_t cpuid)
/////////////////////////////////////////////////
extern "C" void _fini ()
{
}
/////////////////////////////////////////////////