123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- #ifndef _CORE_C_
- #define _CORE_C_
- #include "basics.h"
- #include "device_table.h"
- #include "corefile.h"
- typedef struct _core_mapping core_mapping;
- struct _core_mapping {
-
- int level;
- int space;
- unsigned_word base;
- unsigned_word bound;
- unsigned nr_bytes;
-
- void *free_buffer;
- void *buffer;
-
- device *device;
-
- core_mapping *next;
- };
- struct _core_map {
- core_mapping *first;
- };
- typedef enum {
- core_read_map,
- core_write_map,
- core_execute_map,
- nr_core_map_types,
- } core_map_types;
- struct _core {
- core_map map[nr_core_map_types];
- };
- INLINE_CORE\
- (core *)
- core_create(void)
- {
- return ZALLOC(core);
- }
- INLINE_CORE\
- (core *)
- core_from_device(device *root)
- {
- root = device_root(root);
- ASSERT(strcmp(device_name(root), "core") == 0);
- return device_data(root);
- }
- INLINE_CORE\
- (void)
- core_init(core *memory)
- {
- core_map_types access_type;
- for (access_type = 0;
- access_type < nr_core_map_types;
- access_type++) {
- core_map *map = memory->map + access_type;
-
- core_mapping *curr = map->first;
- while (curr != NULL) {
- core_mapping *tbd = curr;
- curr = curr->next;
- if (tbd->free_buffer != NULL) {
- ASSERT(tbd->buffer != NULL);
- free(tbd->free_buffer);
- }
- free(tbd);
- }
- map->first = NULL;
- }
- }
- INLINE_CORE\
- (core_map *)
- core_readable(core *memory)
- {
- return memory->map + core_read_map;
- }
- INLINE_CORE\
- (core_map *)
- core_writeable(core *memory)
- {
- return memory->map + core_write_map;
- }
- INLINE_CORE\
- (core_map *)
- core_executable(core *memory)
- {
- return memory->map + core_execute_map;
- }
- STATIC_INLINE_CORE\
- (core_mapping *)
- new_core_mapping(attach_type attach,
- int space,
- unsigned_word addr,
- unsigned nr_bytes,
- device *device,
- void *buffer,
- void *free_buffer)
- {
- core_mapping *new_mapping = ZALLOC(core_mapping);
-
- new_mapping->level = attach;
- new_mapping->space = space;
- new_mapping->base = addr;
- new_mapping->nr_bytes = nr_bytes;
- new_mapping->bound = addr + (nr_bytes - 1);
- if (attach == attach_raw_memory) {
- new_mapping->buffer = buffer;
- new_mapping->free_buffer = free_buffer;
- }
- else if (attach >= attach_callback) {
- new_mapping->device = device;
- }
- else {
- error("new_core_mapping() - internal error - unknown attach type %d\n",
- attach);
- }
- return new_mapping;
- }
- STATIC_INLINE_CORE\
- (void)
- core_map_attach(core_map *access_map,
- attach_type attach,
- int space,
- unsigned_word addr,
- unsigned nr_bytes,
- device *client,
- void *buffer,
- void *free_buffer)
- {
-
- core_mapping *next_mapping;
- core_mapping **last_mapping;
-
- if (nr_bytes == 0) {
- device_error(client, "called on core_map_attach() with size zero");
- }
-
- next_mapping = access_map->first;
- last_mapping = &access_map->first;
- while(next_mapping != NULL
- && (next_mapping->level < attach
- || (next_mapping->level == attach
- && next_mapping->bound < addr))) {
-
-
-
- last_mapping = &next_mapping->next;
- next_mapping = next_mapping->next;
- }
-
- ASSERT(next_mapping == NULL || next_mapping->level >= attach);
- if (next_mapping != NULL && next_mapping->level == attach
- && next_mapping->base < (addr + (nr_bytes - 1))) {
- device_error(client, "map overlap when attaching %d:0x%lx (%ld)",
- space, (long)addr, (long)nr_bytes);
- }
-
- *last_mapping = new_core_mapping(attach,
- space, addr, nr_bytes,
- client, buffer, free_buffer);
- (*last_mapping)->next = next_mapping;
- }
- INLINE_CORE\
- (void)
- core_attach(core *memory,
- attach_type attach,
- int space,
- access_type access,
- unsigned_word addr,
- unsigned nr_bytes,
- device *client)
- {
- core_map_types access_map;
- void *buffer;
- void *free_buffer;
- if (attach == attach_raw_memory) {
-
- int padding = (addr % sizeof (unsigned64));
- free_buffer = zalloc(nr_bytes + padding);
- buffer = (char*)free_buffer + padding;
- }
- else {
- buffer = NULL;
- free_buffer = &buffer;
- }
- for (access_map = 0;
- access_map < nr_core_map_types;
- access_map++) {
- switch (access_map) {
- case core_read_map:
- if (access & access_read)
- core_map_attach(memory->map + access_map,
- attach,
- space, addr, nr_bytes,
- client, buffer, free_buffer);
- free_buffer = NULL;
- break;
- case core_write_map:
- if (access & access_write)
- core_map_attach(memory->map + access_map,
- attach,
- space, addr, nr_bytes,
- client, buffer, free_buffer);
- free_buffer = NULL;
- break;
- case core_execute_map:
- if (access & access_exec)
- core_map_attach(memory->map + access_map,
- attach,
- space, addr, nr_bytes,
- client, buffer, free_buffer);
- free_buffer = NULL;
- break;
- default:
- error("core_attach() internal error\n");
- break;
- }
- }
-
- ASSERT(free_buffer == NULL);
- }
- STATIC_INLINE_CORE\
- (core_mapping *)
- core_map_find_mapping(core_map *map,
- unsigned_word addr,
- unsigned nr_bytes,
- cpu *processor,
- unsigned_word cia,
- int abort)
- {
- core_mapping *mapping = map->first;
- ASSERT((addr & (nr_bytes - 1)) == 0);
- ASSERT((addr + (nr_bytes - 1)) >= addr);
- while (mapping != NULL) {
- if (addr >= mapping->base
- && (addr + (nr_bytes - 1)) <= mapping->bound)
- return mapping;
- mapping = mapping->next;
- }
- if (abort)
- error("core_find_mapping() - access to unmaped address, attach a default map to handle this - addr=0x%x nr_bytes=0x%x processor=0x%x cia=0x%x\n",
- addr, nr_bytes, processor, cia);
- return NULL;
- }
- STATIC_INLINE_CORE\
- (void *)
- core_translate(core_mapping *mapping,
- unsigned_word addr)
- {
- return (void *)(((char *)mapping->buffer) + addr - mapping->base);
- }
- INLINE_CORE\
- (unsigned)
- core_map_read_buffer(core_map *map,
- void *buffer,
- unsigned_word addr,
- unsigned len)
- {
- unsigned count = 0;
- while (count < len) {
- unsigned_word raddr = addr + count;
- core_mapping *mapping =
- core_map_find_mapping(map,
- raddr, 1,
- NULL,
- 0,
- 0);
- if (mapping == NULL)
- break;
- if (mapping->device != NULL) {
- int nr_bytes = len - count;
- if (raddr + nr_bytes - 1> mapping->bound)
- nr_bytes = mapping->bound - raddr + 1;
- if (device_io_read_buffer(mapping->device,
- (unsigned_1*)buffer + count,
- mapping->space,
- raddr,
- nr_bytes,
- 0,
- 0 ) != nr_bytes)
- break;
- count += nr_bytes;
- }
- else {
- ((unsigned_1*)buffer)[count] =
- *(unsigned_1*)core_translate(mapping, raddr);
- count += 1;
- }
- }
- return count;
- }
- INLINE_CORE\
- (unsigned)
- core_map_write_buffer(core_map *map,
- const void *buffer,
- unsigned_word addr,
- unsigned len)
- {
- unsigned count = 0;
- while (count < len) {
- unsigned_word raddr = addr + count;
- core_mapping *mapping = core_map_find_mapping(map,
- raddr, 1,
- NULL,
- 0,
- 0);
- if (mapping == NULL)
- break;
- if (mapping->device != NULL) {
- int nr_bytes = len - count;
- if (raddr + nr_bytes - 1 > mapping->bound)
- nr_bytes = mapping->bound - raddr + 1;
- if (device_io_write_buffer(mapping->device,
- (unsigned_1*)buffer + count,
- mapping->space,
- raddr,
- nr_bytes,
- 0,
- 0 ) != nr_bytes)
- break;
- count += nr_bytes;
- }
- else {
- *(unsigned_1*)core_translate(mapping, raddr) =
- ((unsigned_1*)buffer)[count];
- count += 1;
- }
- }
- return count;
- }
- #define N 1
- #include "corefile-n.h"
- #undef N
- #define N 2
- #include "corefile-n.h"
- #undef N
- #define N 4
- #include "corefile-n.h"
- #undef N
- #define N 8
- #include "corefile-n.h"
- #undef N
- #define N word
- #include "corefile-n.h"
- #undef N
- #endif
|