t_stat ioc_cont_reset(DEVICE *dptr, uint16 base, uint8 devnum) { reg_dev(ioc_cont, base, devnum); reg_dev(ioc_cont, base + 1, devnum); ioc_cont_unit[devnum].u3 = 0x00; /* ipc reset */ sim_printf(" ioc_cont[%d]: Reset\n", devnum); sim_printf(" ioc_cont[%d]: Registered at %04X\n", devnum, base); return SCPE_OK; }
t_stat pata_reset (DEVICE *dptr, int32 base) { pata_unit[0].u3 = 0x9B; /* control */ pata_unit[0].u4 = 0xFF; /* Port A */ pata_unit[0].u5 = 0xFF; /* Port B */ pata_unit[0].u6 = 0xFF; /* Port C */ reg_dev(pataa, base); reg_dev(patab, base + 1); reg_dev(patac, base + 2); reg_dev(patas, base + 3); sim_printf(" PATA: Reset\n"); return SCPE_OK; }
t_stat i8259_reset (DEVICE *dptr, int32 base) { switch (i8259_cnt) { case 0: reg_dev(i8259a0, base); reg_dev(i8259b0, base + 1); reg_dev(i8259a0, base + 2); reg_dev(i8259b0, base + 3); i8259_unit[0].u3 = 0x00; /* IRR */ i8259_unit[0].u4 = 0x00; /* ISR */ i8259_unit[0].u5 = 0x00; /* IMR */ sim_printf(" 8259-0: Reset\n"); break; case 1: reg_dev(i8259a1, base); reg_dev(i8259b1, base + 1); reg_dev(i8259a1, base + 2); reg_dev(i8259b1, base + 3); i8259_unit[1].u3 = 0x00; /* IRR */ i8259_unit[1].u4 = 0x00; /* ISR */ i8259_unit[1].u5 = 0x00; /* IMR */ sim_printf(" 8259-1: Reset\n"); break; default: sim_printf(" 8259: Bad device\n"); break; } sim_printf(" 8259-%d: Registered at %02X\n", i8259_cnt, base); i8259_cnt++; return SCPE_OK; }
t_stat i8272_reset(DEVICE *dptr, uint16 base) { if (i8272_devnum >= i8272_NUM) { sim_printf("8251_reset: too many devices!\n"); return 0; } i8272_reset1(i8272_devnum); sim_printf(" 8251-%d: Registered at %03X\n", i8272_devnum, base); i8272_port[i8272_devnum] = reg_dev(i8251d, base); reg_dev(i8251s, base + 1); i8272_unit[i8272_devnum].u6 = i8272_devnum; sim_activate(&i8272_unit[i8272_devnum], i8272_unit[i8272_devnum].wait); /* activate unit */ i8272_devnum++; return SCPE_OK; }
//选择读写的硬盘 static void select_disk(struct disk* hd){ uint8_t reg_device = BIT_DEV_MBS | BIT_DEV_LBA; if(hd->dev_no == 1){ //若是从盘就置DEV位为1 reg_device |= BIT_DEV_DEV; } outb(reg_dev(hd->my_channel),reg_device); }
t_stat isbc202_reset(DEVICE *dptr, uint16 base) { sim_printf("Initializing iSBC-202 FDC Board\n"); if (SBC202_NUM) { sim_printf(" isbc202-%d: Hardware Reset\n", isbc202_fdcnum); sim_printf(" isbc202-%d: Registered at %04X\n", isbc202_fdcnum, base); fdc202[isbc202_fdcnum].baseport = base; reg_dev(isbc2020, base, isbc202_fdcnum); //read status reg_dev(isbc2021, base + 1, isbc202_fdcnum); //read rslt type/write IOPB addr-l reg_dev(isbc2022, base + 2, isbc202_fdcnum); //write IOPB addr-h and start reg_dev(isbc2023, base + 3, isbc202_fdcnum); //read rstl byte reg_dev(isbc2027, base + 7, isbc202_fdcnum); //write reset isbc202 isbc202_reset1(isbc202_fdcnum); isbc202_fdcnum++; } else sim_printf(" No isbc202 installed\n"); return SCPE_OK; }
t_stat i8253_reset (DEVICE *dptr, uint16 port) { if (i8253_devnum > I8253_NUM) { sim_printf("i8253_reset: too many devices!\n"); return SCPE_MEM; } i8253_port[i8253_devnum] = reg_dev(i8253t0, port); reg_dev(i8253t1, port + 1); reg_dev(i8253t2, port + 2); reg_dev(i8253c, port + 3); i8253_unit[i8253_devnum].u3 = 0; /* status */ i8253_unit[i8253_devnum].u4 = 0; /* mode instruction */ i8253_unit[i8253_devnum].u5 = 0; /* command instruction */ i8253_unit[i8253_devnum].u6 = 0; sim_printf(" 8253-%d: Reset\n", i8253_devnum); sim_printf(" 8253-%d: Registered at %03X\n", i8253_devnum, port); sim_activate (&i8253_unit[i8253_devnum], i8253_unit[i8253_devnum].wait); /* activate unit */ i8253_devnum++; return SCPE_OK; }
// device should be disabled static void detect_device(uint port, uchar enable, uchar test, uchar mask) { ps2_device * ps2d; uchar check = 0; ushort type = 0; if (get_config() & mask) { outb(PS2_CMND, enable); if (!(get_config() & mask)) { outb(PS2_CMND, test); do_assert(wait_read()); if (!inb(PS2_DATA)) { ps2_command(port, 0xFF, &check, 1); if (check == 0xAA) { ps2_command(port, 0xF5, NULL, 0); ps2_command(port, 0xF2, (uchar *)(&type), 2); if (type == PS2_NO_DEVICE) { type = PS2_KB_NORMAL; } if (type == PS2_KB_NORMAL || type == PS2_KB_MF2) { ps2_devs[port] = create_stream( sizeof(unsigned), ps2_kb_enable, ps2_kb_disable, ps2_kb_read, NULL ); ps2d = kalloc(sizeof(ps2_device)); ps2d->type = type; ps2d->port = port; ps2_devs[port]->data = ps2d; reg_dev(DEVICE_INPUT, ps2_devs[port]->hndl); enable_device(ps2_devs[port]); } else { ps2_devs[port] = NULL; //TODO: implement } kprintf("PS/2 Device %x detected.\n", type); } } else { outb(PS2_CMND, enable - 1); } } } }
t_stat isbc202_reset(DEVICE *dptr, uint16 base, uint8 devnum) { reg_dev(isbc202, base, devnum); reg_dev(isbc202, base + 1, devnum); reg_dev(isbc202, base + 2, devnum); reg_dev(isbc202, base + 3, devnum); reg_dev(isbc202, base + 4, devnum); reg_dev(isbc202, base + 5, devnum); reg_dev(isbc202, base + 6, devnum); reg_dev(isbc202, base + 7, devnum); isbc202_unit[devnum].u3 = 0x00; /* ipc reset */ sim_printf(" isbc202-%d: Reset\n", devnum); sim_printf(" isbc202-%d: Registered at %04X\n", devnum, base); return SCPE_OK; }
/* * serial_init() called when module is inserted */ static int serial_init(void) { int err; if (option == OPTION_BOTH) { err = reg_dev(PORT_COM1, COM1_MINOR, IRQ_COM1); if (err != 0) { printk(LOG_LEVEL "ERROR: registering COM1 device: %d\n", err); return err; } err = reg_dev(PORT_COM2, COM2_MINOR, IRQ_COM2); if (err != 0) { printk(LOG_LEVEL "ERROR: registering COM2 device: %d\n", err); return err; } } if (option == OPTION_COM1) { err = reg_dev(PORT_COM1, COM1_MINOR, IRQ_COM1); if (err != 0) { printk(LOG_LEVEL "ERROR: registering COM1 device: %d\n", err); return err; } } if (option == OPTION_COM2) { err = reg_dev(PORT_COM2, COM2_MINOR, IRQ_COM2); if (err != 0) { printk(LOG_LEVEL "ERROR: registering COM2 device: %d\n", err); return err; } } return 0; }
//向硬盘控制器写入起始扇区地址及要读写的扇区数 static void select_sector(struct disk* hd,uint32_t lba,uint8_t sec_cnt){ ASSERT(lba <= max_lba); struct ide_channel* channel = hd->my_channel; //写入要读写的扇区数 outb(reg_sect_cnt(channel),sec_cnt); //如果sec_cnt为0,则表示写入256个扇区 //写入lba地址(即扇区号) outb(reg_lba_l(channel),lba); //lba的低8位 outb(reg_lba_m(channel),lba >> 8); //lba的8~15位 outb(reg_lba_h(channel),lba >> 16); //lba的16~23位 //因为lba地址的24~27要存储在device寄存器的0~3位 //无法单独写入这4位,所以在此处把device寄存器再重新写入一次 outb(reg_dev(channel),BIT_DEV_MBS | BIT_DEV_LBA | (hd->dev_no == 1 ? BIT_DEV_DEV : 0) | lba >> 24); }
/* 向硬盘控制器写入起始扇区地址及要读写的扇区数 */ static void select_sector(struct disk* hd, uint32_t lba, uint8_t sec_cnt) { ASSERT(lba <= max_lba); struct ide_channel* channel = hd->my_channel; /* 写入要读写的扇区数*/ outb(reg_sect_cnt(channel), sec_cnt); // 如果sec_cnt为0,则表示写入256个扇区 /* 写入lba地址(即扇区号) */ outb(reg_lba_l(channel), lba); // lba地址的低8位,不用单独取出低8位.outb函数中的汇编指令outb %b0, %w1会只用al。 outb(reg_lba_m(channel), lba >> 8); // lba地址的8~15位 outb(reg_lba_h(channel), lba >> 16); // lba地址的16~23位 /* 因为lba地址的24~27位要存储在device寄存器的0~3位, * 无法单独写入这4位,所以在此处把device寄存器再重新写入一次*/ outb(reg_dev(channel), BIT_DEV_MBS | BIT_DEV_LBA | (hd->dev_no == 1 ? BIT_DEV_DEV : 0) | lba >> 24); }
/****************************** register spi device and attach it to Master driver ******************************/ static int reg_spi_device(void) { int retval = 0; struct spi_board_info spi_device_info = { .modalias = "nrf24l01+", .max_speed_hz = 5000000, .bus_num = 0, .chip_select = 1, .mode = 0, }; struct spi_master *master; master = spi_busnum_to_master(spi_device_info.bus_num); if(!master){ printk(KERN_ALERT "getting master device is failed!!\n"); retval = -ENODEV; goto out; } spi_device = spi_new_device(master,&spi_device_info); if(!spi_device){ printk(KERN_ALERT "registering spi device is failed!!\n"); retval = -ENODEV; goto out; } spi_device->bits_per_word = 8; retval = spi_setup(spi_device); if(retval){ spi_unregister_device(spi_device); goto out; } return 0; out: return retval; } /****************************** Module initialization function ******************************/ static int __init nrf_init(void) { int retval = 0; printk(KERN_INFO "hello from module!!\n"); retval = reg_dev(); if(retval != 0) goto out; retval = reg_spi_device(); if(retval != 0) goto out; radio_init(); return 0; out: return retval; }