--- nono/vm/bus.cpp 2026/04/29 17:04:31 1.1.1.2 +++ nono/vm/bus.cpp 2026/04/29 17:05:10 1.1.1.8 @@ -1,25 +1,33 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // +// +// 物理バスアクセス? +// + +// addr はそれぞれアラインされていること + #include "bus.h" #include "ram.h" IODevice *devtable[256]; -// -// 物理バスアクセス? -// addr はそれぞれアラインされていること -// +// RAM へのアクセスは、アクセスアドレスが direct_ram_size 未満なら ram[] を +// 直接アクセスし、そうでなければデバイスクラス経由でアクセスする。 +// 高速モードでは RAM デバイスを経由すること自体とその中でアクセスウェイトを +// 計算する分を回避したい。 +int direct_ram_size; uint64 vm_phys_read_8(uint32 addr) { uint64 data; - if (addr < ram_size) { - data = ram[HLB(addr)]; + if (addr < direct_ram_size) { + data = mainram[HLB(addr)]; } else { IODevice *dev = ::devtable[addr >> 24]; data = dev->Read8(addr); @@ -32,9 +40,11 @@ vm_phys_read_16(uint32 addr) { uint64 data; -if ((addr & 1))PANIC("unaligned access $%08x", addr); - if (addr < ram_size) { - data = *(uint16 *)&ram[HLW(addr)]; + if (__predict_false((addr & 1) != 0)) + VMPANIC("unaligned access $%08x", addr); + + if (addr < direct_ram_size) { + data = *(uint16 *)&mainram[HLW(addr)]; } else { IODevice *dev = ::devtable[addr >> 24]; data = dev->Read16(addr); @@ -47,10 +57,11 @@ vm_phys_read_32(uint32 addr) { uint64 data; -if ((addr & 3))PANIC("unaligned access $%08x", addr); + if (__predict_false((addr & 3) != 0)) + VMPANIC("unaligned access $%08x", addr); - if (addr < ram_size) { - data = *(uint32 *)&ram[addr]; + if (addr < direct_ram_size) { + data = *(uint32 *)&mainram[addr]; } else { IODevice *dev = ::devtable[addr >> 24]; data = dev->Read32(addr); @@ -61,8 +72,8 @@ if ((addr & 3))PANIC("unaligned access $ uint64 vm_phys_write_8(uint32 addr, uint32 data) { - if (addr < ram_size) { - ram[HLB(addr)] = data; + if (addr < direct_ram_size) { + mainram[HLB(addr)] = data; return 0; } else { IODevice *dev = ::devtable[addr >> 24]; @@ -73,9 +84,11 @@ vm_phys_write_8(uint32 addr, uint32 data uint64 vm_phys_write_16(uint32 addr, uint32 data) { -if ((addr & 1))PANIC("unaligned access $%08x", addr); - if (addr < ram_size) { - *(uint16 *)&ram[HLW(addr)] = data; + if (__predict_false((addr & 1) != 0)) + VMPANIC("unaligned access $%08x", addr); + + if (addr < direct_ram_size) { + *(uint16 *)&mainram[HLW(addr)] = data; return 0; } else { IODevice *dev = ::devtable[addr >> 24]; @@ -86,9 +99,11 @@ if ((addr & 1))PANIC("unaligned access $ uint64 vm_phys_write_32(uint32 addr, uint32 data) { -if ((addr & 3))PANIC("unaligned access $%08x", addr); - if (addr < ram_size) { - *(uint32 *)&ram[addr] = data; + if (__predict_false((addr & 3) != 0)) + VMPANIC("unaligned access $%08x", addr); + + if (addr < direct_ram_size) { + *(uint32 *)&mainram[addr] = data; return 0; } else { IODevice *dev = ::devtable[addr >> 24]; @@ -101,8 +116,8 @@ vm_phys_peek_8(uint32 addr) { uint64 data; - if (addr < ram_size) { - data = ram[HLB(addr)]; + if (addr < direct_ram_size) { + data = mainram[HLB(addr)]; } else { IODevice *dev = ::devtable[addr >> 24]; data = dev->Peek8(addr);