Annotation of qemu/roms/SLOF/clients/net-snk/app/biosemu/mem.c, revision 1.1

1.1     ! root        1: /******************************************************************************
        !             2:  * Copyright (c) 2004, 2008 IBM Corporation
        !             3:  * All rights reserved.
        !             4:  * This program and the accompanying materials
        !             5:  * are made available under the terms of the BSD License
        !             6:  * which accompanies this distribution, and is available at
        !             7:  * http://www.opensource.org/licenses/bsd-license.php
        !             8:  *
        !             9:  * Contributors:
        !            10:  *     IBM Corporation - initial implementation
        !            11:  *****************************************************************************/
        !            12: 
        !            13: #include <stdio.h>
        !            14: #include <stdint.h>
        !            15: #include <cpu.h>
        !            16: #include "debug.h"
        !            17: #include "device.h"
        !            18: #include "x86emu/x86emu.h"
        !            19: #include "biosemu.h"
        !            20: #include <time.h>
        !            21: 
        !            22: // define a check for access to certain (virtual) memory regions (interrupt handlers, BIOS Data Area, ...)
        !            23: #ifdef DEBUG
        !            24: static uint8_t in_check = 0;   // to avoid recursion...
        !            25: uint16_t ebda_segment;
        !            26: uint32_t ebda_size;
        !            27: 
        !            28: //TODO: these macros have grown so large, that they should be changed to an inline function,
        !            29: //just for the sake of readability...
        !            30: 
        !            31: //declare prototypes of the functions to follow, for use in DEBUG_CHECK_VMEM_ACCESS
        !            32: uint8_t my_rdb(uint32_t);
        !            33: uint16_t my_rdw(uint32_t);
        !            34: uint32_t my_rdl(uint32_t);
        !            35: 
        !            36: #define DEBUG_CHECK_VMEM_READ(_addr, _rval) \
        !            37:    if ((debug_flags & DEBUG_CHECK_VMEM_ACCESS) && (in_check == 0)) { \
        !            38:          in_check = 1; \
        !            39:          /* determine ebda_segment and size \
        !            40:           * since we are using my_rdx calls, make sure, this is after setting in_check! */ \
        !            41:          /* offset 03 in BDA is EBDA segment */ \
        !            42:          ebda_segment = my_rdw(0x40e); \
        !            43:          /* first value in ebda is size in KB */ \
        !            44:          ebda_size = my_rdb(ebda_segment << 4) * 1024; \
        !            45:                        /* check Interrupt Vector Access (0000:0000h - 0000:0400h) */ \
        !            46:                        if (_addr < 0x400) { \
        !            47:                                DEBUG_PRINTF_CS_IP("%s: read from Interrupt Vector %x --> %x\n", \
        !            48:                                                __FUNCTION__, _addr / 4, _rval); \
        !            49:                        } \
        !            50:                        /* access to BIOS Data Area (0000:0400h - 0000:0500h)*/ \
        !            51:                        else if ((_addr >= 0x400) && (addr < 0x500)) { \
        !            52:                                DEBUG_PRINTF_CS_IP("%s: read from BIOS Data Area: addr: %x --> %x\n", \
        !            53:                                                __FUNCTION__, _addr, _rval); \
        !            54:                                /* dump registers */ \
        !            55:                                /* x86emu_dump_xregs(); */ \
        !            56:                        } \
        !            57:                        /* access to first 64k of memory... */ \
        !            58:                        else if (_addr < 0x10000) { \
        !            59:                                DEBUG_PRINTF_CS_IP("%s: read from segment 0000h: addr: %x --> %x\n", \
        !            60:                                                __FUNCTION__, _addr, _rval); \
        !            61:                                /* dump registers */ \
        !            62:                                /* x86emu_dump_xregs(); */ \
        !            63:                        } \
        !            64:                        /* read from PMM_CONV_SEGMENT */ \
        !            65:                        else if ((_addr <= ((PMM_CONV_SEGMENT << 4) | 0xffff)) && (_addr >= (PMM_CONV_SEGMENT << 4))) { \
        !            66:                                DEBUG_PRINTF_CS_IP("%s: read from PMM Segment %04xh: addr: %x --> %x\n", \
        !            67:                                                __FUNCTION__, PMM_CONV_SEGMENT, _addr, _rval); \
        !            68:                                /* HALT_SYS(); */ \
        !            69:                                /* dump registers */ \
        !            70:                                /* x86emu_dump_xregs(); */ \
        !            71:                        } \
        !            72:                        /* read from PNP_DATA_SEGMENT */ \
        !            73:                        else if ((_addr <= ((PNP_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (PNP_DATA_SEGMENT << 4))) { \
        !            74:                                DEBUG_PRINTF_CS_IP("%s: read from PnP Data Segment %04xh: addr: %x --> %x\n", \
        !            75:                                                __FUNCTION__, PNP_DATA_SEGMENT, _addr, _rval); \
        !            76:                                /* HALT_SYS(); */ \
        !            77:                                /* dump registers */ \
        !            78:                                /* x86emu_dump_xregs(); */ \
        !            79:                        } \
        !            80:                        /* read from EBDA Segment */ \
        !            81:                        else if ((_addr <= ((ebda_segment << 4) | (ebda_size - 1))) && (_addr >= (ebda_segment << 4))) { \
        !            82:                                DEBUG_PRINTF_CS_IP("%s: read from Extended BIOS Data Area %04xh, size: %04x: addr: %x --> %x\n", \
        !            83:                                                __FUNCTION__, ebda_segment, ebda_size, _addr, _rval); \
        !            84:                        } \
        !            85:                        /* read from BIOS_DATA_SEGMENT */ \
        !            86:                        else if ((_addr <= ((BIOS_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (BIOS_DATA_SEGMENT << 4))) { \
        !            87:                                DEBUG_PRINTF_CS_IP("%s: read from BIOS Data Segment %04xh: addr: %x --> %x\n", \
        !            88:                                                __FUNCTION__, BIOS_DATA_SEGMENT, _addr, _rval); \
        !            89:                                /* for PMM debugging */ \
        !            90:                                /*if (_addr == BIOS_DATA_SEGMENT << 4) { \
        !            91:                                        X86EMU_trace_on(); \
        !            92:                                        M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F; \
        !            93:                                }*/ \
        !            94:                                /* dump registers */ \
        !            95:                                /* x86emu_dump_xregs(); */ \
        !            96:                        } \
        !            97:          in_check = 0; \
        !            98:    }
        !            99: #define DEBUG_CHECK_VMEM_WRITE(_addr, _val) \
        !           100:    if ((debug_flags & DEBUG_CHECK_VMEM_ACCESS) && (in_check == 0)) { \
        !           101:          in_check = 1; \
        !           102:          /* determine ebda_segment and size \
        !           103:           * since we are using my_rdx calls, make sure, this is after setting in_check! */ \
        !           104:          /* offset 03 in BDA is EBDA segment */ \
        !           105:          ebda_segment = my_rdw(0x40e); \
        !           106:          /* first value in ebda is size in KB */ \
        !           107:          ebda_size = my_rdb(ebda_segment << 4) * 1024; \
        !           108:                        /* check Interrupt Vector Access (0000:0000h - 0000:0400h) */ \
        !           109:                        if (_addr < 0x400) { \
        !           110:                                DEBUG_PRINTF_CS_IP("%s: write to Interrupt Vector %x <-- %x\n", \
        !           111:                                                __FUNCTION__, _addr / 4, _val); \
        !           112:                        } \
        !           113:                        /* access to BIOS Data Area (0000:0400h - 0000:0500h)*/ \
        !           114:                        else if ((_addr >= 0x400) && (addr < 0x500)) { \
        !           115:                                DEBUG_PRINTF_CS_IP("%s: write to BIOS Data Area: addr: %x <-- %x\n", \
        !           116:                                                __FUNCTION__, _addr, _val); \
        !           117:                                /* dump registers */ \
        !           118:                                /* x86emu_dump_xregs(); */ \
        !           119:                        } \
        !           120:                        /* access to first 64k of memory...*/ \
        !           121:                        else if (_addr < 0x10000) { \
        !           122:                                DEBUG_PRINTF_CS_IP("%s: write to segment 0000h: addr: %x <-- %x\n", \
        !           123:                                                __FUNCTION__, _addr, _val); \
        !           124:                                /* dump registers */ \
        !           125:                                /* x86emu_dump_xregs(); */ \
        !           126:                        } \
        !           127:                        /* write to PMM_CONV_SEGMENT... */ \
        !           128:                        else if ((_addr <= ((PMM_CONV_SEGMENT << 4) | 0xffff)) && (_addr >= (PMM_CONV_SEGMENT << 4))) { \
        !           129:                                DEBUG_PRINTF_CS_IP("%s: write to PMM Segment %04xh: addr: %x <-- %x\n", \
        !           130:                                                __FUNCTION__, PMM_CONV_SEGMENT, _addr, _val); \
        !           131:                                /* dump registers */ \
        !           132:                                /* x86emu_dump_xregs(); */ \
        !           133:                        } \
        !           134:                        /* write to PNP_DATA_SEGMENT... */ \
        !           135:                        else if ((_addr <= ((PNP_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (PNP_DATA_SEGMENT << 4))) { \
        !           136:                                DEBUG_PRINTF_CS_IP("%s: write to PnP Data Segment %04xh: addr: %x <-- %x\n", \
        !           137:                                                __FUNCTION__, PNP_DATA_SEGMENT, _addr, _val); \
        !           138:                                /* dump registers */ \
        !           139:                                /* x86emu_dump_xregs(); */ \
        !           140:                        } \
        !           141:                        /* write to EBDA Segment... */ \
        !           142:                        else if ((_addr <= ((ebda_segment << 4) | (ebda_size - 1))) && (_addr >= (ebda_segment << 4))) { \
        !           143:                                DEBUG_PRINTF_CS_IP("%s: write to Extended BIOS Data Area %04xh, size: %04x: addr: %x <-- %x\n", \
        !           144:                                                __FUNCTION__, ebda_segment, ebda_size, _addr, _val); \
        !           145:                        } \
        !           146:                        /* write to BIOS_DATA_SEGMENT... */ \
        !           147:                        else if ((_addr <= ((BIOS_DATA_SEGMENT << 4) | 0xffff)) && (_addr >= (BIOS_DATA_SEGMENT << 4))) { \
        !           148:                                DEBUG_PRINTF_CS_IP("%s: write to BIOS Data Segment %04xh: addr: %x <-- %x\n", \
        !           149:                                                __FUNCTION__, BIOS_DATA_SEGMENT, _addr, _val); \
        !           150:                                /* dump registers */ \
        !           151:                                /* x86emu_dump_xregs(); */ \
        !           152:                        } \
        !           153:                        /* write to current CS segment... */ \
        !           154:                        else if ((_addr < ((M.x86.R_CS << 4) | 0xffff)) && (_addr > (M.x86.R_CS << 4))) { \
        !           155:                                DEBUG_PRINTF_CS_IP("%s: write to CS segment %04xh: addr: %x <-- %x\n", \
        !           156:                                                __FUNCTION__, M.x86.R_CS, _addr, _val); \
        !           157:                                /* dump registers */ \
        !           158:                                /* x86emu_dump_xregs(); */ \
        !           159:                        } \
        !           160:          in_check = 0; \
        !           161:    }
        !           162: #else
        !           163: #define DEBUG_CHECK_VMEM_READ(_addr, _rval)
        !           164: #define DEBUG_CHECK_VMEM_WRITE(_addr, _val)
        !           165: #endif
        !           166: 
        !           167: //defined in net-snk/kernel/timer.c
        !           168: extern uint64_t get_time(void);
        !           169: 
        !           170: void update_time(uint32_t);
        !           171: 
        !           172: // read byte from memory
        !           173: uint8_t
        !           174: my_rdb(uint32_t addr)
        !           175: {
        !           176:        uint64_t translated_addr = addr;
        !           177:        uint8_t translated = dev_translate_address(&translated_addr);
        !           178:        uint8_t rval;
        !           179:        if (translated != 0) {
        !           180:                //translation successfull, access VGA Memory (BAR or Legacy...)
        !           181:                DEBUG_PRINTF_MEM("%s(%08x): access to VGA Memory\n",
        !           182:                                 __FUNCTION__, addr);
        !           183:                //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr);
        !           184:                set_ci();
        !           185:                rval = *((uint8_t *) translated_addr);
        !           186:                clr_ci();
        !           187:                DEBUG_PRINTF_MEM("%s(%08x) VGA --> %02x\n", __FUNCTION__, addr,
        !           188:                                 rval);
        !           189:                return rval;
        !           190:        } else if (addr > M.mem_size) {
        !           191:                DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n",
        !           192:                             __FUNCTION__, addr);
        !           193:                //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1);
        !           194:                HALT_SYS();
        !           195:        } else {
        !           196:                /* read from virtual memory */
        !           197:                rval = *((uint8_t *) (M.mem_base + addr));
        !           198:                DEBUG_CHECK_VMEM_READ(addr, rval);
        !           199:                return rval;
        !           200:        }
        !           201:        return -1;
        !           202: }
        !           203: 
        !           204: //read word from memory
        !           205: uint16_t
        !           206: my_rdw(uint32_t addr)
        !           207: {
        !           208:        uint64_t translated_addr = addr;
        !           209:        uint8_t translated = dev_translate_address(&translated_addr);
        !           210:        uint16_t rval;
        !           211:        if (translated != 0) {
        !           212:                //translation successfull, access VGA Memory (BAR or Legacy...)
        !           213:                DEBUG_PRINTF_MEM("%s(%08x): access to VGA Memory\n",
        !           214:                                 __FUNCTION__, addr);
        !           215:                //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr);
        !           216:                // check for legacy memory, because of the remapping to BARs, the reads must
        !           217:                // be byte reads...
        !           218:                if ((addr >= 0xa0000) && (addr < 0xc0000)) {
        !           219:                        //read bytes a using my_rdb, because of the remapping to BARs
        !           220:                        //words may not be contiguous in memory, so we need to translate
        !           221:                        //every address...
        !           222:                        rval = ((uint8_t) my_rdb(addr)) |
        !           223:                            (((uint8_t) my_rdb(addr + 1)) << 8);
        !           224:                } else {
        !           225:                        if ((translated_addr & (uint64_t) 0x1) == 0) {
        !           226:                                // 16 bit aligned access...
        !           227:                                set_ci();
        !           228:                                rval = in16le((void *) translated_addr);
        !           229:                                clr_ci();
        !           230:                        } else {
        !           231:                                // unaligned access, read single bytes
        !           232:                                set_ci();
        !           233:                                rval = (*((uint8_t *) translated_addr)) |
        !           234:                                    (*((uint8_t *) translated_addr + 1) << 8);
        !           235:                                clr_ci();
        !           236:                        }
        !           237:                }
        !           238:                DEBUG_PRINTF_MEM("%s(%08x) VGA --> %04x\n", __FUNCTION__, addr,
        !           239:                                 rval);
        !           240:                return rval;
        !           241:        } else if (addr > M.mem_size) {
        !           242:                DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n",
        !           243:                             __FUNCTION__, addr);
        !           244:                //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1);
        !           245:                HALT_SYS();
        !           246:        } else {
        !           247:                /* read from virtual memory */
        !           248:                rval = in16le((void *) (M.mem_base + addr));
        !           249:                DEBUG_CHECK_VMEM_READ(addr, rval);
        !           250:                return rval;
        !           251:        }
        !           252:        return -1;
        !           253: }
        !           254: 
        !           255: //read long from memory
        !           256: uint32_t
        !           257: my_rdl(uint32_t addr)
        !           258: {
        !           259:        uint64_t translated_addr = addr;
        !           260:        uint8_t translated = dev_translate_address(&translated_addr);
        !           261:        uint32_t rval;
        !           262:        if (translated != 0) {
        !           263:                //translation successfull, access VGA Memory (BAR or Legacy...)
        !           264:                DEBUG_PRINTF_MEM("%s(%x): access to VGA Memory\n",
        !           265:                                 __FUNCTION__, addr);
        !           266:                //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr);
        !           267:                // check for legacy memory, because of the remapping to BARs, the reads must
        !           268:                // be byte reads...
        !           269:                if ((addr >= 0xa0000) && (addr < 0xc0000)) {
        !           270:                        //read bytes a using my_rdb, because of the remapping to BARs
        !           271:                        //dwords may not be contiguous in memory, so we need to translate
        !           272:                        //every address...
        !           273:                        rval = ((uint8_t) my_rdb(addr)) |
        !           274:                            (((uint8_t) my_rdb(addr + 1)) << 8) |
        !           275:                            (((uint8_t) my_rdb(addr + 2)) << 16) |
        !           276:                            (((uint8_t) my_rdb(addr + 3)) << 24);
        !           277:                } else {
        !           278:                        if ((translated_addr & (uint64_t) 0x3) == 0) {
        !           279:                                // 32 bit aligned access...
        !           280:                                set_ci();
        !           281:                                rval = in32le((void *) translated_addr);
        !           282:                                clr_ci();
        !           283:                        } else {
        !           284:                                // unaligned access, read single bytes
        !           285:                                set_ci();
        !           286:                                rval = (*((uint8_t *) translated_addr)) |
        !           287:                                    (*((uint8_t *) translated_addr + 1) << 8) |
        !           288:                                    (*((uint8_t *) translated_addr + 2) << 16) |
        !           289:                                    (*((uint8_t *) translated_addr + 3) << 24);
        !           290:                                clr_ci();
        !           291:                        }
        !           292:                }
        !           293:                DEBUG_PRINTF_MEM("%s(%08x) VGA --> %08x\n", __FUNCTION__, addr,
        !           294:                                 rval);
        !           295:                //HALT_SYS();
        !           296:                return rval;
        !           297:        } else if (addr > M.mem_size) {
        !           298:                DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n",
        !           299:                             __FUNCTION__, addr);
        !           300:                //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1);
        !           301:                HALT_SYS();
        !           302:        } else {
        !           303:                /* read from virtual memory */
        !           304:                rval = in32le((void *) (M.mem_base + addr));
        !           305:                switch (addr) {
        !           306:                case 0x46c:
        !           307:                        //BDA Time Data, update it, before reading
        !           308:                        update_time(rval);
        !           309:                        rval = in32le((void *) (M.mem_base + addr));
        !           310:                        break;
        !           311:                }
        !           312:                DEBUG_CHECK_VMEM_READ(addr, rval);
        !           313:                return rval;
        !           314:        }
        !           315:        return -1;
        !           316: }
        !           317: 
        !           318: //write byte to memory
        !           319: void
        !           320: my_wrb(uint32_t addr, uint8_t val)
        !           321: {
        !           322:        uint64_t translated_addr = addr;
        !           323:        uint8_t translated = dev_translate_address(&translated_addr);
        !           324:        if (translated != 0) {
        !           325:                //translation successfull, access VGA Memory (BAR or Legacy...)
        !           326:                DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n",
        !           327:                                 __FUNCTION__, addr, val);
        !           328:                //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr);
        !           329:                set_ci();
        !           330:                *((uint8_t *) translated_addr) = val;
        !           331:                clr_ci();
        !           332:        } else if (addr > M.mem_size) {
        !           333:                DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n",
        !           334:                             __FUNCTION__, addr);
        !           335:                //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1);
        !           336:                HALT_SYS();
        !           337:        } else {
        !           338:                /* write to virtual memory */
        !           339:                DEBUG_CHECK_VMEM_WRITE(addr, val);
        !           340:                *((uint8_t *) (M.mem_base + addr)) = val;
        !           341:        }
        !           342: }
        !           343: 
        !           344: void
        !           345: my_wrw(uint32_t addr, uint16_t val)
        !           346: {
        !           347:        uint64_t translated_addr = addr;
        !           348:        uint8_t translated = dev_translate_address(&translated_addr);
        !           349:        if (translated != 0) {
        !           350:                //translation successfull, access VGA Memory (BAR or Legacy...)
        !           351:                DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n",
        !           352:                                 __FUNCTION__, addr, val);
        !           353:                //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n", __FUNCTION__, addr, translated_addr);
        !           354:                // check for legacy memory, because of the remapping to BARs, the reads must
        !           355:                // be byte reads...
        !           356:                if ((addr >= 0xa0000) && (addr < 0xc0000)) {
        !           357:                        //read bytes a using my_rdb, because of the remapping to BARs
        !           358:                        //words may not be contiguous in memory, so we need to translate
        !           359:                        //every address...
        !           360:                        my_wrb(addr, (uint8_t) (val & 0x00FF));
        !           361:                        my_wrb(addr + 1, (uint8_t) ((val & 0xFF00) >> 8));
        !           362:                } else {
        !           363:                        if ((translated_addr & (uint64_t) 0x1) == 0) {
        !           364:                                // 16 bit aligned access...
        !           365:                                set_ci();
        !           366:                                out16le((void *) translated_addr, val);
        !           367:                                clr_ci();
        !           368:                        } else {
        !           369:                                // unaligned access, write single bytes
        !           370:                                set_ci();
        !           371:                                *((uint8_t *) translated_addr) =
        !           372:                                    (uint8_t) (val & 0x00FF);
        !           373:                                *((uint8_t *) translated_addr + 1) =
        !           374:                                    (uint8_t) ((val & 0xFF00) >> 8);
        !           375:                                clr_ci();
        !           376:                        }
        !           377:                }
        !           378:        } else if (addr > M.mem_size) {
        !           379:                DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n",
        !           380:                             __FUNCTION__, addr);
        !           381:                //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1);
        !           382:                HALT_SYS();
        !           383:        } else {
        !           384:                /* write to virtual memory */
        !           385:                DEBUG_CHECK_VMEM_WRITE(addr, val);
        !           386:                out16le((void *) (M.mem_base + addr), val);
        !           387:        }
        !           388: }
        !           389: void
        !           390: my_wrl(uint32_t addr, uint32_t val)
        !           391: {
        !           392:        uint64_t translated_addr = addr;
        !           393:        uint8_t translated = dev_translate_address(&translated_addr);
        !           394:        if (translated != 0) {
        !           395:                //translation successfull, access VGA Memory (BAR or Legacy...)
        !           396:                DEBUG_PRINTF_MEM("%s(%x, %x): access to VGA Memory\n",
        !           397:                                 __FUNCTION__, addr, val);
        !           398:                //DEBUG_PRINTF_MEM("%s(%08x): translated_addr: %llx\n",  __FUNCTION__, addr, translated_addr);
        !           399:                // check for legacy memory, because of the remapping to BARs, the reads must
        !           400:                // be byte reads...
        !           401:                if ((addr >= 0xa0000) && (addr < 0xc0000)) {
        !           402:                        //read bytes a using my_rdb, because of the remapping to BARs
        !           403:                        //words may not be contiguous in memory, so we need to translate
        !           404:                        //every address...
        !           405:                        my_wrb(addr, (uint8_t) (val & 0x000000FF));
        !           406:                        my_wrb(addr + 1, (uint8_t) ((val & 0x0000FF00) >> 8));
        !           407:                        my_wrb(addr + 2, (uint8_t) ((val & 0x00FF0000) >> 16));
        !           408:                        my_wrb(addr + 3, (uint8_t) ((val & 0xFF000000) >> 24));
        !           409:                } else {
        !           410:                        if ((translated_addr & (uint64_t) 0x3) == 0) {
        !           411:                                // 32 bit aligned access...
        !           412:                                set_ci();
        !           413:                                out32le((void *) translated_addr, val);
        !           414:                                clr_ci();
        !           415:                        } else {
        !           416:                                // unaligned access, write single bytes
        !           417:                                set_ci();
        !           418:                                *((uint8_t *) translated_addr) =
        !           419:                                    (uint8_t) (val & 0x000000FF);
        !           420:                                *((uint8_t *) translated_addr + 1) =
        !           421:                                    (uint8_t) ((val & 0x0000FF00) >> 8);
        !           422:                                *((uint8_t *) translated_addr + 2) =
        !           423:                                    (uint8_t) ((val & 0x00FF0000) >> 16);
        !           424:                                *((uint8_t *) translated_addr + 3) =
        !           425:                                    (uint8_t) ((val & 0xFF000000) >> 24);
        !           426:                                clr_ci();
        !           427:                        }
        !           428:                }
        !           429:        } else if (addr > M.mem_size) {
        !           430:                DEBUG_PRINTF("%s(%08x): Memory Access out of range!\n",
        !           431:                             __FUNCTION__, addr);
        !           432:                //disassemble_forward(M.x86.saved_cs, M.x86.saved_ip, 1);
        !           433:                HALT_SYS();
        !           434:        } else {
        !           435:                /* write to virtual memory */
        !           436:                DEBUG_CHECK_VMEM_WRITE(addr, val);
        !           437:                out32le((void *) (M.mem_base + addr), val);
        !           438:        }
        !           439: }
        !           440: 
        !           441: //update time in BIOS Data Area
        !           442: //DWord at offset 0x6c is the timer ticks since midnight, timer is running at 18Hz
        !           443: //byte at 0x70 is timer overflow (set if midnight passed since last call to interrupt 1a function 00
        !           444: //cur_val is the current value, of offset 6c...
        !           445: void
        !           446: update_time(uint32_t cur_val)
        !           447: {
        !           448:        //for convenience, we let the start of timebase be at midnight, we currently dont support
        !           449:        //real daytime anyway...
        !           450:        uint64_t ticks_per_day = tb_freq * 60 * 24;
        !           451:        // at 18Hz a period is ~55ms, converted to ticks (tb_freq is ticks/second)
        !           452:        uint32_t period_ticks = (55 * tb_freq) / 1000;
        !           453:        uint64_t curr_time = get_time();
        !           454:        uint64_t ticks_since_midnight = curr_time % ticks_per_day;
        !           455:        uint32_t periods_since_midnight = ticks_since_midnight / period_ticks;
        !           456:        // if periods since midnight is smaller than last value, set overflow
        !           457:        // at BDA Offset 0x70
        !           458:        if (periods_since_midnight < cur_val) {
        !           459:                my_wrb(0x470, 1);
        !           460:        }
        !           461:        // store periods since midnight at BDA offset 0x6c
        !           462:        my_wrl(0x46c, periods_since_midnight);
        !           463: }

unix.superglobalmegacorp.com

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