user: 请将这段汇编代码片段转换成等效的C代码:

```asm
<hiusb_start_hcd>:
  endbr64
  push   %rbx
  mov    $0x0,%ebx
  mov    %rbx,%rdi
  call   <local_irq_save@plt>
  mov    $0x1204016c,%esi
  mov    $0x301,%edi
  call   <writel@plt>
  mov    $0x2,%edi
  call   <wait_ms@plt>
  mov    $0x1204012c,%edi
  call   <readl@plt>
  or     $0x20,%ah
  mov    %eax,%edi
  mov    $0x1204012c,%esi
  call   <writel@plt>
  mov    $0xa,%edi
  call   <wait_ms@plt>
  mov    $0x12040120,%edi
  call   <readl@plt>
  or     $0x8,%ah
  mov    %eax,%edi
  mov    $0x12040120,%esi
  call   <writel@plt>
  mov    $0xa,%edi
  call   <wait_ms@plt>
  mov    $0x12040120,%edi
  call   <readl@plt>
  and    $0xf7,%ah
  mov    %eax,%edi
  mov    $0x12040120,%esi
  call   <writel@plt>
  mov    $0xa,%edi
  call   <wait_ms@plt>
  mov    $0x1204016c,%esi
  mov    $0x1,%edi
  call   <writel@plt>
  mov    $0x2,%edi
  call   <wait_ms@plt>
  mov    $0x1212012c,%edi
  call   <readl@plt>
  or     $0x426,%eax
  mov    %eax,%edi
  mov    $0x1212012c,%esi
  call   <writel@plt>
  mov    $0x64,%edi
  call   <wait_ms@plt>
  mov    $0x1212012c,%esi
  mov    $0x0,%edi
  call   <writel@plt>
  mov    $0x2,%edi
  call   <wait_ms@plt>
  mov    $0x1204012c,%edi
  call   <readl@plt>
  or     $0x3f,%ah
  mov    %eax,%edi
  mov    $0x1204012c,%esi
  call   <writel@plt>
  mov    $0x64,%edi
  call   <wait_ms@plt>
  mov    $0x1204012c,%edi
  call   <readl@plt>
  and    $0xdf,%ah
  mov    %eax,%edi
  mov    $0x1204012c,%esi
  call   <writel@plt>
  mov    $0x64,%edi
  call   <wait_ms@plt>
  mov    $0x1100c2c0,%edi
  call   <readl@plt>
  or     $0x80000000,%eax
  mov    %eax,%edi
  mov    $0x1100c2c0,%esi
  call   <writel@plt>
  mov    $0x1100c200,%edi
  call   <readl@plt>
  and    $0xffffffa7,%eax
  mov    %eax,%edi
  mov    $0x1100c200,%esi
  call   <writel@plt>
  mov    $0x14,%edi
  call   <wait_ms@plt>
  mov    $0x1100c110,%edi
  call   <readl@plt>
  and    $0xcf,%ah
  mov    %eax,%edi
  or     $0x1000,%edi
  mov    $0x1100c110,%esi
  call   <writel@plt>
  mov    $0x12120094,%esi
  mov    $0x0,%edi
  call   <writel@plt>
  mov    $0xa,%edi
  call   <udelay@plt>
  mov    $0x12120094,%esi
  mov    $0x1820,%edi
  call   <writel@plt>
  mov    $0x64,%edi
  call   <udelay@plt>
  mov    $0x12120094,%esi
  mov    $0xa,%edi
  call   <writel@plt>
  mov    $0xa,%edi
  call   <udelay@plt>
  mov    $0x12120094,%esi
  mov    $0xbb2a,%edi
  call   <writel@plt>
  mov    $0x64,%edi
  call   <udelay@plt>
  mov    $0x1100c2c0,%edi
  call   <readl@plt>
  and    $0x7ffdffc1,%eax
  mov    %eax,%edi
  or     $0xa,%edi
  mov    $0x1100c2c0,%esi
  call   <writel@plt>
  mov    $0x64,%edi
  call   <wait_ms@plt>
  mov    $0x1100c108,%esi
  mov    $0x23100000,%edi
  call   <writel@plt>
  mov    $0x1100c10c,%esi
  mov    $0x23100000,%edi
  call   <writel@plt>
  mov    $0x14,%edi
  call   <wait_ms@plt>
  mov    %rbx,%rdi
  call   <local_irq_restore@plt>
  pop    %rbx
  ret
```

assistant: ```c
void hiusb_start_hcd(void) {
  unsigned long flags;
  unsigned int reg;
  local_irq_save(flags);
  writel(0x301, (0x1204016c));
  wait_ms(2);
  reg = readl((0x12040000 + 0x12c));
  reg |= (1 << 13);
  writel(reg, (0x12040000 + 0x12c));
  wait_ms(10);
  reg = readl((0x12040000 + 0x120));
  reg |= (1 << 11);
  writel(reg, (0x12040000 + 0x120));
  wait_ms(10);
  reg = readl((0x12040000 + 0x120));
  reg &= ~(1 << 11);
  writel(reg, (0x12040000 + 0x120));
  wait_ms(10);
  writel(0x1, (0x1204016c));
  wait_ms(2);
  reg = readl((0x12120000 + 0x12c));
  reg |= ((0x1 << 5) | (0x6 << 0) | (0x4 << 8));
  writel(reg, (0x12120000 + 0x12c));
  wait_ms(100);
  writel(0x0, (0x12120000 + 0x12c));
  wait_ms(2);
  reg = readl((0x12040000 + 0x12c));
  reg |= (1 << 13);
  reg |= (1 << 12);
  reg |= (1 << 11);
  reg |= (1 << 10);
  reg |= (1 << 9);
  reg |= (1 << 8);
  writel(reg, (0x12040000 + 0x12c));
  wait_ms(100);
  reg = readl((0x12040000 + 0x12c));
  reg &= ~((1 << 13));
  writel(reg, (0x12040000 + 0x12c));
  wait_ms(100);
  reg = readl((0x11000000) + 0xC2C0);
  reg |= (1 << 31);
  writel(reg, (0x11000000) + 0xC2C0);
  reg = readl((0x11000000) + 0xC200);
  reg &= ~(1 << 4);
  reg &= ~(1 << 3);
  reg &= ~(0x1 << 6);
  writel(reg, (0x11000000) + 0xC200);
  wait_ms(20);
  reg = readl((0x11000000) + 0xC110);
  reg &= ~((1 << 12) | (1 << 13));
  reg |= (1 << 12);
  writel(reg, (0x11000000) + 0xC110);
  writel(0x0, (0x12120000 + 0x94));
  udelay(10);
  writel(0x1820, (0x12120000 + 0x94));
  udelay(100);
  writel(0xa, (0x12120000 + 0x94));
  udelay(10);
  writel(0xbb2a, (0x12120000 + 0x94));
  udelay(100);
  reg = readl((0x11000000) + 0xC2C0);
  reg &= ~(1 << 31);
  reg &= ~(1 << 17);
  reg &= ~(0x7 << 3);
  reg |= (1 << 3);
  reg &= ~(0x3 << 1);
  reg |= (1 << 1);
  writel(reg, (0x11000000) + 0xC2C0);
  wait_ms(100);
  reg = (1 << 29) | (3 << 24) | (0x10 << 16);
  writel(reg, (0x11000000) + 0xC108);
  reg = (1 << 29) | (3 << 24) | (0x10 << 16);
  writel(reg, (0x11000000) + 0xC10C);
  wait_ms(20);
  local_irq_restore(flags);
}
```