--- nono/vm/bus.cpp 2026/04/29 17:04:35 1.1.1.3 +++ nono/vm/bus.cpp 2026/04/29 17:04:41 1.1.1.5 @@ -9,6 +9,13 @@ IODevice *devtable[256]; +// RAM へのアクセスは、アクセスアドレスが direct_ram_size 未満なら ram[] を +// 直接アクセスし、そうでなければデバイスクラス経由でアクセスする。 +// 高速モードでは RAM デバイスを経由すること自体とその中でアクセスウェイトを +// 計算する分を回避したい。 +// スケジューライベントのように、CPU コアが動作していない時に書き換えること。 +int direct_ram_size; + // // 物理バスアクセス? // addr はそれぞれアラインされていること @@ -19,7 +26,7 @@ vm_phys_read_8(uint32 addr) { uint64 data; - if (addr < ram_size) { + if (addr < direct_ram_size) { data = ram[HLB(addr)]; } else { IODevice *dev = ::devtable[addr >> 24]; @@ -33,8 +40,10 @@ vm_phys_read_16(uint32 addr) { uint64 data; -if ((addr & 1))PANIC("unaligned access $%08x", addr); - if (addr < ram_size) { + if (__predict_false(addr & 1)) + PANIC("unaligned access $%08x", addr); + + if (addr < direct_ram_size) { data = *(uint16 *)&ram[HLW(addr)]; } else { IODevice *dev = ::devtable[addr >> 24]; @@ -48,9 +57,10 @@ vm_phys_read_32(uint32 addr) { uint64 data; -if ((addr & 3))PANIC("unaligned access $%08x", addr); + if (__predict_false(addr & 3)) + PANIC("unaligned access $%08x", addr); - if (addr < ram_size) { + if (addr < direct_ram_size) { data = *(uint32 *)&ram[addr]; } else { IODevice *dev = ::devtable[addr >> 24]; @@ -62,7 +72,7 @@ if ((addr & 3))PANIC("unaligned access $ uint64 vm_phys_write_8(uint32 addr, uint32 data) { - if (addr < ram_size) { + if (addr < direct_ram_size) { ram[HLB(addr)] = data; return 0; } else { @@ -74,8 +84,10 @@ 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) { + if (__predict_false(addr & 1)) + PANIC("unaligned access $%08x", addr); + + if (addr < direct_ram_size) { *(uint16 *)&ram[HLW(addr)] = data; return 0; } else { @@ -87,8 +99,10 @@ 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) { + if (__predict_false(addr & 3)) + PANIC("unaligned access $%08x", addr); + + if (addr < direct_ram_size) { *(uint32 *)&ram[addr] = data; return 0; } else { @@ -102,7 +116,7 @@ vm_phys_peek_8(uint32 addr) { uint64 data; - if (addr < ram_size) { + if (addr < direct_ram_size) { data = ram[HLB(addr)]; } else { IODevice *dev = ::devtable[addr >> 24];