Annotation of qemu/roms/SLOF/clients/net-snk/app/biosemu/mem.c, revision 1.1.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.