NJU-ProjectN/nemu ics2023 initialized
NJU-ProjectN/nemu eb63cf3568dbf4e0c3c6ef462e6ec685550fabbc Merge pull request #76 from rijuyuezhu/master
This commit is contained in:
parent
1efe03efb9
commit
2824efad33
141 changed files with 19573 additions and 0 deletions
70
nemu/src/device/io/map.c
Normal file
70
nemu/src/device/io/map.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <isa.h>
|
||||
#include <memory/host.h>
|
||||
#include <memory/vaddr.h>
|
||||
#include <device/map.h>
|
||||
|
||||
#define IO_SPACE_MAX (2 * 1024 * 1024)
|
||||
|
||||
static uint8_t *io_space = NULL;
|
||||
static uint8_t *p_space = NULL;
|
||||
|
||||
uint8_t* new_space(int size) {
|
||||
uint8_t *p = p_space;
|
||||
// page aligned;
|
||||
size = (size + (PAGE_SIZE - 1)) & ~PAGE_MASK;
|
||||
p_space += size;
|
||||
assert(p_space - io_space < IO_SPACE_MAX);
|
||||
return p;
|
||||
}
|
||||
|
||||
static void check_bound(IOMap *map, paddr_t addr) {
|
||||
if (map == NULL) {
|
||||
Assert(map != NULL, "address (" FMT_PADDR ") is out of bound at pc = " FMT_WORD, addr, cpu.pc);
|
||||
} else {
|
||||
Assert(addr <= map->high && addr >= map->low,
|
||||
"address (" FMT_PADDR ") is out of bound {%s} [" FMT_PADDR ", " FMT_PADDR "] at pc = " FMT_WORD,
|
||||
addr, map->name, map->low, map->high, cpu.pc);
|
||||
}
|
||||
}
|
||||
|
||||
static void invoke_callback(io_callback_t c, paddr_t offset, int len, bool is_write) {
|
||||
if (c != NULL) { c(offset, len, is_write); }
|
||||
}
|
||||
|
||||
void init_map() {
|
||||
io_space = malloc(IO_SPACE_MAX);
|
||||
assert(io_space);
|
||||
p_space = io_space;
|
||||
}
|
||||
|
||||
word_t map_read(paddr_t addr, int len, IOMap *map) {
|
||||
assert(len >= 1 && len <= 8);
|
||||
check_bound(map, addr);
|
||||
paddr_t offset = addr - map->low;
|
||||
invoke_callback(map->callback, offset, len, false); // prepare data to read
|
||||
word_t ret = host_read(map->space + offset, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void map_write(paddr_t addr, int len, word_t data, IOMap *map) {
|
||||
assert(len >= 1 && len <= 8);
|
||||
check_bound(map, addr);
|
||||
paddr_t offset = addr - map->low;
|
||||
host_write(map->space + offset, len, data);
|
||||
invoke_callback(map->callback, offset, len, true);
|
||||
}
|
63
nemu/src/device/io/mmio.c
Normal file
63
nemu/src/device/io/mmio.c
Normal file
|
@ -0,0 +1,63 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <device/map.h>
|
||||
#include <memory/paddr.h>
|
||||
|
||||
#define NR_MAP 16
|
||||
|
||||
static IOMap maps[NR_MAP] = {};
|
||||
static int nr_map = 0;
|
||||
|
||||
static IOMap* fetch_mmio_map(paddr_t addr) {
|
||||
int mapid = find_mapid_by_addr(maps, nr_map, addr);
|
||||
return (mapid == -1 ? NULL : &maps[mapid]);
|
||||
}
|
||||
|
||||
static void report_mmio_overlap(const char *name1, paddr_t l1, paddr_t r1,
|
||||
const char *name2, paddr_t l2, paddr_t r2) {
|
||||
panic("MMIO region %s@[" FMT_PADDR ", " FMT_PADDR "] is overlapped "
|
||||
"with %s@[" FMT_PADDR ", " FMT_PADDR "]", name1, l1, r1, name2, l2, r2);
|
||||
}
|
||||
|
||||
/* device interface */
|
||||
void add_mmio_map(const char *name, paddr_t addr, void *space, uint32_t len, io_callback_t callback) {
|
||||
assert(nr_map < NR_MAP);
|
||||
paddr_t left = addr, right = addr + len - 1;
|
||||
if (in_pmem(left) || in_pmem(right)) {
|
||||
report_mmio_overlap(name, left, right, "pmem", PMEM_LEFT, PMEM_RIGHT);
|
||||
}
|
||||
for (int i = 0; i < nr_map; i++) {
|
||||
if (left <= maps[i].high && right >= maps[i].low) {
|
||||
report_mmio_overlap(name, left, right, maps[i].name, maps[i].low, maps[i].high);
|
||||
}
|
||||
}
|
||||
|
||||
maps[nr_map] = (IOMap){ .name = name, .low = addr, .high = addr + len - 1,
|
||||
.space = space, .callback = callback };
|
||||
Log("Add mmio map '%s' at [" FMT_PADDR ", " FMT_PADDR "]",
|
||||
maps[nr_map].name, maps[nr_map].low, maps[nr_map].high);
|
||||
|
||||
nr_map ++;
|
||||
}
|
||||
|
||||
/* bus interface */
|
||||
word_t mmio_read(paddr_t addr, int len) {
|
||||
return map_read(addr, len, fetch_mmio_map(addr));
|
||||
}
|
||||
|
||||
void mmio_write(paddr_t addr, int len, word_t data) {
|
||||
map_write(addr, len, data, fetch_mmio_map(addr));
|
||||
}
|
49
nemu/src/device/io/port-io.c
Normal file
49
nemu/src/device/io/port-io.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/***************************************************************************************
|
||||
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
||||
*
|
||||
* NEMU is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the Mulan PSL v2 for more details.
|
||||
***************************************************************************************/
|
||||
|
||||
#include <device/map.h>
|
||||
|
||||
#define PORT_IO_SPACE_MAX 65535
|
||||
|
||||
#define NR_MAP 16
|
||||
static IOMap maps[NR_MAP] = {};
|
||||
static int nr_map = 0;
|
||||
|
||||
/* device interface */
|
||||
void add_pio_map(const char *name, ioaddr_t addr, void *space, uint32_t len, io_callback_t callback) {
|
||||
assert(nr_map < NR_MAP);
|
||||
assert(addr + len <= PORT_IO_SPACE_MAX);
|
||||
maps[nr_map] = (IOMap){ .name = name, .low = addr, .high = addr + len - 1,
|
||||
.space = space, .callback = callback };
|
||||
Log("Add port-io map '%s' at [" FMT_PADDR ", " FMT_PADDR "]",
|
||||
maps[nr_map].name, maps[nr_map].low, maps[nr_map].high);
|
||||
|
||||
nr_map ++;
|
||||
}
|
||||
|
||||
/* CPU interface */
|
||||
uint32_t pio_read(ioaddr_t addr, int len) {
|
||||
assert(addr + len - 1 < PORT_IO_SPACE_MAX);
|
||||
int mapid = find_mapid_by_addr(maps, nr_map, addr);
|
||||
assert(mapid != -1);
|
||||
return map_read(addr, len, &maps[mapid]);
|
||||
}
|
||||
|
||||
void pio_write(ioaddr_t addr, int len, uint32_t data) {
|
||||
assert(addr + len - 1 < PORT_IO_SPACE_MAX);
|
||||
int mapid = find_mapid_by_addr(maps, nr_map, addr);
|
||||
assert(mapid != -1);
|
||||
map_write(addr, len, data, &maps[mapid]);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue