From bdbe2cfb03aef46aecd8cda438dc7c242199e2bb Mon Sep 17 00:00:00 2001 From: Volker Ruppert Date: Sun, 10 Jul 2011 09:30:04 +0000 Subject: [PATCH] - added more values in register_state() (not yet complete) - don't add reserved bitfields to the save/restore tree - some fixes for big endian machines - TODO: init max_packet_size in USB devices, find test case, ... --- bochs/iodev/usb_xhci.cc | 154 +++++++++++++++++++++++++--------------- bochs/iodev/usb_xhci.h | 2 +- 2 files changed, 96 insertions(+), 60 deletions(-) diff --git a/bochs/iodev/usb_xhci.cc b/bochs/iodev/usb_xhci.cc index da4f0b517..877538367 100644 --- a/bochs/iodev/usb_xhci.cc +++ b/bochs/iodev/usb_xhci.cc @@ -407,13 +407,12 @@ bx_bool bx_usb_xhci_c::save_hc_state(void) /// Currently does nothing... Bit8u buffer[256]; - bx_phy_address p; + Bit64u p; DEV_MEM_READ_PHYSICAL_BLOCK((bx_phy_address) BX_XHCI_THIS hub.op_regs.HcDCBAAP.dcbaap, 16, buffer); - p = (bx_phy_address) (*(Bit64u *) &buffer[0]); - DEV_MEM_READ_PHYSICAL_BLOCK(p, 16, buffer); - p = (bx_phy_address) (*(Bit64u *) &buffer[0]); - + ReadHostQWordFromLittleEndian(&buffer[0], p); + DEV_MEM_READ_PHYSICAL_BLOCK((bx_phy_address)p, 16, buffer); + ReadHostQWordFromLittleEndian(&buffer[0], p); memset(buffer, 0x22, 256); @@ -447,8 +446,8 @@ bx_bool bx_usb_xhci_c::restore_hc_state(void) void bx_usb_xhci_c::register_state(void) { unsigned i; - char portnum[8]; - bx_list_c *hub, *port, *reg, *reg_grp; + char tmpname[16]; + bx_list_c *hub, *port, *reg, *reg_grp, *reg_grp1; bx_list_c *list = new bx_list_c(SIM->get_bochs_root(), "usb_xhci", "USB xHCI State"); hub = new bx_list_c(list, "hub", 8); @@ -460,37 +459,30 @@ void bx_usb_xhci_c::register_state(void) new bx_shadow_num_c(reg_grp, "HcCParams", &BX_XHCI_THIS hub.cap_regs.HcCParams, BASE_HEX); new bx_shadow_num_c(reg_grp, "DBOFF", &BX_XHCI_THIS hub.cap_regs.DBOFF, BASE_HEX); new bx_shadow_num_c(reg_grp, "RTSOFF", &BX_XHCI_THIS hub.cap_regs.RTSOFF, BASE_HEX); + reg_grp = new bx_list_c(hub, "op_regs", 7); - reg = new bx_list_c(reg_grp, "HcCommand", 11); - new bx_shadow_num_c(reg, "RsvdP1", &BX_XHCI_THIS hub.op_regs.HcCommand.RsvdP1, BASE_HEX); + reg = new bx_list_c(reg_grp, "HcCommand", 9); new bx_shadow_bool_c(reg, "eu3s", &BX_XHCI_THIS hub.op_regs.HcCommand.eu3s); new bx_shadow_bool_c(reg, "ewe", &BX_XHCI_THIS hub.op_regs.HcCommand.ewe); new bx_shadow_bool_c(reg, "crs", &BX_XHCI_THIS hub.op_regs.HcCommand.crs); new bx_shadow_bool_c(reg, "css", &BX_XHCI_THIS hub.op_regs.HcCommand.css); new bx_shadow_bool_c(reg, "lhcrst", &BX_XHCI_THIS hub.op_regs.HcCommand.lhcrst); - new bx_shadow_num_c(reg, "RsvdP0", &BX_XHCI_THIS hub.op_regs.HcCommand.RsvdP0, BASE_HEX); new bx_shadow_bool_c(reg, "hsee", &BX_XHCI_THIS hub.op_regs.HcCommand.hsee); new bx_shadow_bool_c(reg, "inte", &BX_XHCI_THIS hub.op_regs.HcCommand.inte); new bx_shadow_bool_c(reg, "hcrst", &BX_XHCI_THIS hub.op_regs.HcCommand.hcrst); new bx_shadow_bool_c(reg, "rs", &BX_XHCI_THIS hub.op_regs.HcCommand.rs); - reg = new bx_list_c(reg_grp, "HcStatus", 12); - new bx_shadow_num_c(reg, "RsvdZ1", &BX_XHCI_THIS hub.op_regs.HcStatus.RsvdZ1, BASE_HEX); + reg = new bx_list_c(reg_grp, "HcStatus", 9); new bx_shadow_bool_c(reg, "hce", &BX_XHCI_THIS hub.op_regs.HcStatus.hce); new bx_shadow_bool_c(reg, "cnr", &BX_XHCI_THIS hub.op_regs.HcStatus.cnr); new bx_shadow_bool_c(reg, "sre", &BX_XHCI_THIS hub.op_regs.HcStatus.sre); new bx_shadow_bool_c(reg, "rss", &BX_XHCI_THIS hub.op_regs.HcStatus.rss); new bx_shadow_bool_c(reg, "sss", &BX_XHCI_THIS hub.op_regs.HcStatus.sss); - new bx_shadow_num_c(reg, "RsvdZ0", &BX_XHCI_THIS hub.op_regs.HcStatus.RsvdZ0, BASE_HEX); new bx_shadow_bool_c(reg, "pcd", &BX_XHCI_THIS hub.op_regs.HcStatus.pcd); new bx_shadow_bool_c(reg, "eint", &BX_XHCI_THIS hub.op_regs.HcStatus.eint); new bx_shadow_bool_c(reg, "hse", &BX_XHCI_THIS hub.op_regs.HcStatus.hse); - new bx_shadow_bool_c(reg, "RsvdZ2", &BX_XHCI_THIS hub.op_regs.HcStatus.RsvdZ2); new bx_shadow_bool_c(reg, "hch", &BX_XHCI_THIS hub.op_regs.HcStatus.hch); - reg = new bx_list_c(reg_grp, "HcPageSize", 2); - new bx_shadow_num_c(reg, "Rsvd", &BX_XHCI_THIS hub.op_regs.HcPageSize.Rsvd, BASE_HEX); - new bx_shadow_num_c(reg, "pagesize", &BX_XHCI_THIS hub.op_regs.HcPageSize.pagesize, BASE_HEX); + new bx_shadow_num_c(reg_grp, "HcPageSize", &BX_XHCI_THIS hub.op_regs.HcPageSize.pagesize, BASE_HEX); reg = new bx_list_c(reg_grp, "HcNotification", 17); - new bx_shadow_num_c(reg, "RsvdP", &BX_XHCI_THIS hub.op_regs.HcNotification.RsvdP, BASE_HEX); new bx_shadow_bool_c(reg, "n15", &BX_XHCI_THIS hub.op_regs.HcNotification.n15); new bx_shadow_bool_c(reg, "n14", &BX_XHCI_THIS hub.op_regs.HcNotification.n14); new bx_shadow_bool_c(reg, "n13", &BX_XHCI_THIS hub.op_regs.HcNotification.n13); @@ -509,34 +501,68 @@ void bx_usb_xhci_c::register_state(void) new bx_shadow_bool_c(reg, "n0", &BX_XHCI_THIS hub.op_regs.HcNotification.n0); reg = new bx_list_c(reg_grp, "HcCrcr", 6); new bx_shadow_num_c(reg, "crc", &BX_XHCI_THIS hub.op_regs.HcCrcr.crc, BASE_HEX); - new bx_shadow_num_c(reg, "RsvdP", &BX_XHCI_THIS hub.op_regs.HcCrcr.RsvdP, BASE_HEX); new bx_shadow_bool_c(reg, "crr", &BX_XHCI_THIS hub.op_regs.HcCrcr.crr); new bx_shadow_bool_c(reg, "ca", &BX_XHCI_THIS hub.op_regs.HcCrcr.ca); new bx_shadow_bool_c(reg, "cs", &BX_XHCI_THIS hub.op_regs.HcCrcr.cs); new bx_shadow_bool_c(reg, "rcs", &BX_XHCI_THIS hub.op_regs.HcCrcr.rcs); - reg = new bx_list_c(reg_grp, "HcDCBAAP", 2); - new bx_shadow_num_c(reg, "dcbaap", &BX_XHCI_THIS hub.op_regs.HcDCBAAP.dcbaap, BASE_HEX); - new bx_shadow_num_c(reg, "RsvdZ", &BX_XHCI_THIS hub.op_regs.HcDCBAAP.RsvdZ, BASE_HEX); - reg = new bx_list_c(reg_grp, "HcConfig", 2); - new bx_shadow_num_c(reg, "RsvdP", &BX_XHCI_THIS hub.op_regs.HcConfig.RsvdP, BASE_HEX); - new bx_shadow_num_c(reg, "MaxSlotsEn", &BX_XHCI_THIS hub.op_regs.HcConfig.MaxSlotsEn, BASE_HEX); - reg_grp = new bx_list_c(hub, "runtime_regs", 6); - reg = new bx_list_c(reg_grp, "mfindex", 2); - new bx_shadow_num_c(reg, "RsvdP", &BX_XHCI_THIS hub.runtime_regs.mfindex.RsvdP, BASE_HEX); - new bx_shadow_num_c(reg, "index", &BX_XHCI_THIS hub.runtime_regs.mfindex.index, BASE_HEX); - reg = new bx_list_c(reg_grp, "interrupter", INTERRUPTERS); - // TODO - for (i=0; i> 32); break; } } else @@ -1687,7 +1715,7 @@ void bx_usb_xhci_c::process_command_ring(void) { struct TRB trb; int i, slot, slot_type, ep, comp_code = 0, new_addr = 0, bsr = 0; - Bit32u a_flags = 0, d_flags; + Bit32u a_flags = 0, d_flags, tmpval1, tmpval2; Bit64u org_addr; Bit8u buffer[CONTEXT_SIZE + 2048]; struct SLOT_CONTEXT slot_context; @@ -1768,7 +1796,9 @@ void bx_usb_xhci_c::process_command_ring(void) if (BX_XHCI_THIS hub.slots[slot].enabled == 1) { DEV_MEM_READ_PHYSICAL_BLOCK((bx_phy_address) trb.parameter, (CONTEXT_SIZE + (CONTEXT_SIZE * 2)), buffer); bsr = ((trb.command & (1<<9)) == (1<<9)); - if ((*(Bit32u *) &buffer[0] == 0x00) && (*(Bit32u *) &buffer[4] == 0x03)) { + ReadHostDWordFromLittleEndian(&buffer[0], tmpval1); + ReadHostDWordFromLittleEndian(&buffer[4], tmpval2); + if ((tmpval1 == 0x00) && (tmpval2 == 0x03)) { // Use temporary slot and ep context incase there is an error we don't modify the main contexts copy_slot_from_buffer(&slot_context, &buffer[CONTEXT_SIZE]); copy_ep_from_buffer(&ep_context, &buffer[CONTEXT_SIZE + CONTEXT_SIZE]); @@ -1785,7 +1815,8 @@ void bx_usb_xhci_c::process_command_ring(void) comp_code = CONTEXT_STATE_ERROR; } else { // BSR flag is clear if (BX_XHCI_THIS hub.slots[slot].slot_context.slot_state <= SLOT_STATE_DEFAULT) { - int port_num = (((*(Bit32u *) &buffer[CONTEXT_SIZE + 4]) & (0xFF<<16)) >> 16) - 1; // slot:port_num is 1 based + ReadHostDWordFromLittleEndian(&buffer[CONTEXT_SIZE + 4], tmpval1); + int port_num = ((tmpval1 & (0xFF<<16)) >> 16) - 1; // slot:port_num is 1 based new_addr = create_unique_address(slot); if (send_set_address(new_addr, port_num) == 0) { slot_context.slot_state = SLOT_STATE_ADRESSED; @@ -1828,7 +1859,7 @@ void bx_usb_xhci_c::process_command_ring(void) slot = TRB_GET_SLOT(trb.command); // slots are 1 based if (BX_XHCI_THIS hub.slots[slot].enabled == 1) { DEV_MEM_READ_PHYSICAL_BLOCK((bx_phy_address) trb.parameter, (CONTEXT_SIZE + (CONTEXT_SIZE * 32)), buffer); - a_flags = *(Bit32u *) &buffer[4]; + ReadHostDWordFromLittleEndian(&buffer[4], a_flags); // only the Slot context and EP1 (control EP) contexts are evaluated. Section 6.2.3.3 // If the slot is not addresses or configured, then return error // FIXME: XHCI specs 1.0, page 102 says DEFAULT or higher, while page 321 states higher than DEFAULT!!! @@ -1916,8 +1947,8 @@ void bx_usb_xhci_c::process_command_ring(void) bx_bool dc = TRB_DC(trb.command); if (BX_XHCI_THIS hub.slots[slot].enabled) { DEV_MEM_READ_PHYSICAL_BLOCK((bx_phy_address) trb.parameter, (CONTEXT_SIZE + (CONTEXT_SIZE * 32)), buffer); - d_flags = *(Bit32u *) &buffer[0]; - a_flags = *(Bit32u *) &buffer[4]; + ReadHostDWordFromLittleEndian(&buffer[0], d_flags); + ReadHostDWordFromLittleEndian(&buffer[4], a_flags); copy_slot_from_buffer(&slot_context, &buffer[CONTEXT_SIZE]); // so we get entry_count if (BX_XHCI_THIS hub.slots[slot].slot_context.slot_state == SLOT_STATE_CONFIGURED) { @@ -2092,6 +2123,8 @@ void bx_usb_xhci_c::init_event_ring(const unsigned interrupter) bx_phy_address addr = (bx_phy_address) BX_XHCI_THIS hub.runtime_regs.interrupter[interrupter].erstba.erstabadd; int i; Bit8u entry[16]; + Bit32u val32; + Bit64u val64; BX_XHCI_THIS hub.ring_members.event_rings[interrupter].rcs = 1; BX_XHCI_THIS hub.ring_members.event_rings[interrupter].count = 0; @@ -2108,7 +2141,9 @@ void bx_usb_xhci_c::init_event_ring(const unsigned interrupter) addr = (bx_phy_address) BX_XHCI_THIS hub.runtime_regs.interrupter[interrupter].erstba.erstabadd; for (i=0; iparameter = *(Bit64u *) &buffer[0]; - trb->status = *(Bit32u *) &buffer[8]; - trb->command = *(Bit32u *) &buffer[12]; + ReadHostQWordFromLittleEndian(&buffer[0], trb->parameter); + ReadHostDWordFromLittleEndian(&buffer[8], trb->status); + ReadHostDWordFromLittleEndian(&buffer[12], trb->command); } void bx_usb_xhci_c::write_TRB(bx_phy_address addr, const Bit64u parameter, const Bit32u status, const Bit32u command) { Bit8u buffer[16]; - *(Bit64u *) &buffer[0] = parameter; - *(Bit32u *) &buffer[8] = status; - *(Bit32u *) &buffer[12] = command; + WriteHostQWordToLittleEndian(&buffer[0], parameter); + WriteHostDWordToLittleEndian(&buffer[8], status); + WriteHostDWordToLittleEndian(&buffer[12], command); DEV_MEM_WRITE_PHYSICAL_BLOCK(addr, 16, buffer); } @@ -2376,7 +2411,8 @@ int bx_usb_xhci_c::send_set_address(const int addr, const int port_num) int ret; USBPacket packet; static Bit8u setup_address[8] = { 0, 0x05, 0, 0, 0, 0, 0 }; - *(Bit16u *) &setup_address[2] = addr; + + WriteHostWordToLittleEndian(&setup_address[2], addr); packet.pid = USB_TOKEN_SETUP; packet.devep = 0; diff --git a/bochs/iodev/usb_xhci.h b/bochs/iodev/usb_xhci.h index 16e12fd80..542be7161 100644 --- a/bochs/iodev/usb_xhci.h +++ b/bochs/iodev/usb_xhci.h @@ -413,7 +413,7 @@ typedef struct { Bit8u tmode; // 4 bit Test Mode = 0x0 RO Bit16u RsvdP; // 11 bit reserved and preseved = 0x000 RW bx_bool hle; // 1 bit hardware LPM enable = 0b RW - Bit8u l1dslot; // 7 bit L1 Device Slot = 0x00 RW + Bit8u l1dslot; // 8 bit L1 Device Slot = 0x00 RW Bit8u hird; // 4 bit Host Initiated Resume Durat = 0x0 RW bx_bool rwe; // 1 bit Remote Wakeup Enable = 0b RW Bit8u l1s; // 3 bit L1 Status = 000b RO