Annotation of nono/vm/prom.cpp, revision 1.1.1.11

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
1.1.1.10  root        7: //
1.1       root        8: // PROM (LUNA-I, LUNA88K 共通)
1.1.1.8   root        9: //
1.1.1.10  root       10: 
1.1.1.8   root       11: // IODevice
                     12: //    |
                     13: //    +-- ROMDevice (LoadROM()、ウェイト、マスク等を持つ)
                     14: //    |     |
                     15: //    |     |  +------------+
                     16: //    |     +--| PROMDevice |  (LUNA* の PROM)
                     17: //    |     |  +------------+
                     18: //    |     |
                     19: //    |     +-- IPLROM1Device (X680x0 の IPLROM 後半)
                     20: //    |     +-- IPLROM2Device (X680x0 の IPLROM 前半)
                     21: //    |     +-- CGROMDevice   (X680x0 の CGROM)
                     22: //    |     +-- LunaPROMEmuDevice   (LUNA PROM エミュレーションの共通部分)
                     23: //    |           |
                     24: //    |           +-- Luna1PROMEmuDevice   (LUNA1 の PROM エミュレーション)
                     25: //    |           +-- Luna88kPROMEmuDevice (LUNA88K の PROM エミュレーション)
                     26: //    |
                     27: //    |   +-------------+
                     28: //    +-- | PROM0Device | (LUNA* のブートページ切り替え用プロキシ)
                     29: //    |   +-------------+
                     30: //    |
                     31: //    +-- IPLROM0Device   (X680x0 のブートページ切り替え用プロキシ)
1.1       root       32: 
                     33: #include "prom.h"
                     34: #include "config.h"
1.1.1.8   root       35: #include "ethernet.h"
1.1       root       36: #include "mainapp.h"
1.1.1.11! root       37: #include "vm.h"
1.1       root       38: 
1.1.1.10  root       39: // グローバル参照用
                     40: PROM0Device *gPROM0;
1.1.1.11! root       41: PROMDevice *gPROM;
1.1.1.8   root       42: 
                     43: //
                     44: // PROM0
                     45: //
                     46: // PROM0 は PROM のブートページ担当。
                     47: // これ自身はメモリ領域を持たず PROM へのプロキシとして動作する。
                     48: //
                     49: // リセット後最初の ROM 領域への書き込みアクセスでブートページを RAM に
                     50: // 切り替える。
                     51: // LUNA のブートページのアドレス範囲は不明なので、とりあえず devtable の
                     52: // 1区画である 16MB ($0000'0000..$00ff'ffff) とする。実害はない。
                     53: 
                     54: // コンストラクタ
                     55: PROM0Device::PROM0Device()
1.1.1.10  root       56:        : inherited("PROM(BOOT)")
1.1.1.8   root       57: {
                     58:        ClearAlias();
1.1.1.10  root       59:        AddAlias("PROMBOOT");
1.1.1.8   root       60: }
                     61: 
                     62: // デストラクタ
                     63: PROM0Device::~PROM0Device()
                     64: {
1.1.1.10  root       65:        gPROM0 = NULL;
1.1.1.8   root       66: }
                     67: 
                     68: bool
                     69: PROM0Device::Init()
                     70: {
1.1.1.10  root       71:        prom = gPROM;
1.1.1.8   root       72:        return true;
                     73: }
                     74: 
1.1.1.10  root       75: // リセット
1.1.1.8   root       76: void
1.1.1.10  root       77: PROM0Device::ResetHard(bool poweron)
1.1.1.8   root       78: {
                     79:        gVM->SwitchBootPageToROM(this);
                     80: }
                     81: 
                     82: // アドレスデコーダ
                     83: /*static*/ inline uint32
                     84: PROM0Device::Decoder(uint32 addr)
                     85: {
                     86:        // ここはブートページか ROM かの比較だけで十分 (それ以外はここに来ない)
                     87:        if (addr < 0x0100'0000) {
                     88:                addr += 0x4100'0000;
                     89:        }
                     90:        return addr;
                     91: }
                     92: 
                     93: uint64
                     94: PROM0Device::Read8(uint32 addr)
                     95: {
                     96:        addr = Decoder(addr);
                     97:        return prom->Read8(addr);
                     98: }
                     99: 
                    100: uint64
                    101: PROM0Device::Read16(uint32 addr)
                    102: {
                    103:        addr = Decoder(addr);
                    104:        return prom->Read16(addr);
                    105: }
                    106: 
                    107: uint64
                    108: PROM0Device::Read32(uint32 addr)
                    109: {
                    110:        addr = Decoder(addr);
                    111:        return prom->Read32(addr);
                    112: }
                    113: 
                    114: // LUNA では PROM へのライトアクセスでブートページを RAM に切り替えている。
                    115: // - LUNA-I では最初に $41000000.B への書き込みがあるが、
                    116: //   それ以降も $41000000.L への書き込みが(複数回)あるようだ。
                    117: // - LUNA88K では $4100000c.L への書き込みがある。
                    118: //
                    119: // よってアドレスを定めず PROM 全域への書き込みで最初の1回だけ発動する
                    120: // ようにしておく。サイズも今の所ワード(16bit)アクセスは確認してないけど
                    121: // 統一的に対処しておく。
                    122: uint64
                    123: PROM0Device::Write()
                    124: {
                    125:        gVM->SwitchBootPageToRAM(this);
                    126: 
                    127:        // バスエラーは起きない
                    128:        return 0;
                    129: }
                    130: 
                    131: uint64
                    132: PROM0Device::Write8(uint32 addr, uint32 data)
                    133: {
                    134:        return Write();
                    135: }
                    136: 
                    137: uint64
                    138: PROM0Device::Write16(uint32 addr, uint32 data)
                    139: {
                    140:        return Write();
                    141: }
                    142: 
                    143: uint64
                    144: PROM0Device::Write32(uint32 addr, uint32 data)
                    145: {
                    146:        return Write();
                    147: }
                    148: 
                    149: uint64
                    150: PROM0Device::Peek8(uint32 addr)
                    151: {
                    152:        addr = Decoder(addr);
                    153:        return prom->Peek8(addr);
                    154: }
                    155: 
                    156: 
                    157: //
                    158: // PROM
                    159: //
                    160: 
1.1       root      161: // コンストラクタ
                    162: PROMDevice::PROMDevice()
1.1.1.7   root      163:        : inherited("PROM")
1.1       root      164: {
                    165:        devaddr = 0x41000000;
1.1.1.8   root      166: 
                    167:        // LUNA では ROM への書き込みは何も起きない
                    168:        write_op = 0;
1.1       root      169: }
                    170: 
                    171: // デストラクタ
                    172: PROMDevice::~PROMDevice()
                    173: {
1.1.1.10  root      174:        gPROM = NULL;
1.1       root      175: }
                    176: 
                    177: bool
                    178: PROMDevice::Init()
                    179: {
1.1.1.11! root      180:        VMType vmtype = gMainApp.GetVMType();
1.1       root      181: 
                    182:        switch (vmtype) {
1.1.1.11! root      183:         case VMType::LUNA1:
1.1.1.6   root      184:                return InitLuna1();
1.1       root      185: 
1.1.1.11! root      186:         case VMType::LUNA88K:
1.1       root      187:                return InitLuna88k();
                    188: 
                    189:         default:
1.1.1.11! root      190:                PANIC("unknown vmtype %d", (int)vmtype);
1.1       root      191:        }
                    192: }
                    193: 
                    194: // LUNA-I の場合
                    195: bool
1.1.1.6   root      196: PROMDevice::InitLuna1()
1.1       root      197: {
                    198:        devlen = 128 * 1024;
                    199:        mask = devlen - 1;
                    200: 
                    201:        // ファイル名が存在してる時しかここに来ない
                    202:        const ConfigItem& item = gConfig->Find("prom-image");
                    203:        if (LoadROM(item.AsString().c_str(), devlen) == false) {
                    204:                return false;
                    205:        }
                    206: 
1.1.1.8   root      207:        // XXX アクセスウェイトは未調査。とりあえず RAM と同程度にしておく
                    208:        wait = 1;
                    209: 
1.1.1.2   root      210:        // ROM バージョンを確認。確認されてるのは
                    211:        // V4.02 (Wed Oct 12 17:07:11 1988)
                    212:        // V4.22 (Thu Jul 27 11:45:42 1989)
                    213:        // V4.25
                    214:        //
                    215:        // とりあえず V4.22 は +$00d390 からにタイムスタンプ文字列があるので
                    216:        // それで判別してみる。
                    217:        //00d390 54 68 75 20 4a 75 6c 20 32 37 20 31 31 3a 34 35 |Thu Jul 27 11:45|
                    218:        //00d3a0 3a 34 32 20 31 39 38 39 00 00 00 00 4e 56 fd f8 |:42 1989....NV..|
                    219: 
                    220:        if (strcmp((const char *)&mem[0xd390], "Thu Jul 27 11:45:42 1989") == 0) {
                    221:                // V4.22
1.1.1.10  root      222:                putmsg(1, "V4.22 detected");
1.1.1.2   root      223: 
                    224:                // MAC アドレスは ROM に書き込まれているので、ここで上書き
                    225:                if (strcmp((const char *)&mem[0x1ffd8], "ENADDR") != 0) {
                    226:                        warnx("ENADDR not found; unknown ROM V4.22 variants?");
                    227:                        return false;
                    228:                }
                    229: 
                    230:                // MAC アドレスは12桁の16進数文字列として書き込まれている。例えば
                    231:                // 前半の 00:00:0A 部分は 30 30 30 30 30 41 "00000A" という感じ。
                    232:                const macaddr_t macaddr = gEthernet->GetMacAddr();
1.1.1.11! root      233:                memcpy(&imagebuf[0x1ffe0], macaddr.ToString().c_str(), 12);
1.1.1.2   root      234: 
                    235:                // SCSI デバッグビット
                    236:                bool scsi_debug_bit = gConfig->Find(".prom-scsi-debug").AsInt();
1.1.1.11! root      237:                imagebuf[0x4100981d - 0x41000000] = (scsi_debug_bit) ? 0x01 : 0;
1.1.1.2   root      238:        } else {
                    239:                // 他の ROM は何も分からないので何もしない。
1.1.1.10  root      240:                putmsg(0, "Unknown PROM Version");
1.1       root      241:        }
                    242: 
                    243:        return true;
                    244: }
                    245: 
                    246: // LUNA88K の場合
                    247: bool
                    248: PROMDevice::InitLuna88k()
                    249: {
                    250:        devlen = 256 * 1024;
                    251:        mask = devlen - 1;
                    252: 
                    253:        // ファイル名が存在してる時しかここに来ない
                    254:        const ConfigItem& item = gConfig->Find("prom-image");
                    255:        if (LoadROM(item.AsString().c_str(), devlen) == false) {
                    256:                return false;
                    257:        }
                    258: 
1.1.1.8   root      259:        // XXX アクセスウェイトは未調査。とりあえず RAM と同程度にしておく
                    260:        wait = 3;
                    261: 
1.1       root      262:        return true;
                    263: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.