色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Rt-Smart在riscv中的初始化流程

冬至子 ? 來源:HAHABO ? 作者:HAHABO ? 2023-10-12 14:15 ? 次閱讀

qemu-virt-riscv介紹

簡介

Virt板是一個不對應于任何真實硬件的平臺;它是為虛擬機設計的。如果你只是想運行Linux等客戶機,而不關心重現真實世界硬件的特殊性和局限性,那么它是推薦的板卡類型。

內存空間布局(包括外設地址)

static const MemMapEntry virt_memmap[] = {
[VIRT_DEBUG] = { 0x0, 0x100 },
[VIRT_MROM] = { 0x1000, 0xf000 },
[VIRT_TEST] = { 0x100000, 0x1000 },
[VIRT_RTC] = { 0x101000, 0x1000 },
[VIRT_CLINT] = { 0x2000000, 0x10000 },
[VIRT_ACLINT_SSWI] = { 0x2F00000, 0x4000 },
[VIRT_PCIE_PIO] = { 0x3000000, 0x10000 },
[VIRT_PLIC] = { 0xc000000, VIRT_PLIC_SIZE(VIRT_CPUS_MAX * 2) },
[VIRT_APLIC_M] = { 0xc000000, APLIC_SIZE(VIRT_CPUS_MAX) },
[VIRT_APLIC_S] = { 0xd000000, APLIC_SIZE(VIRT_CPUS_MAX) },
[VIRT_UART0] = { 0x10000000, 0x100 }, / 串口設備 /
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
[VIRT_FW_CFG] = { 0x10100000, 0x18 },
[VIRT_FLASH] = { 0x20000000, 0x4000000 },
[VIRT_IMSIC_M] = { 0x24000000, VIRT_IMSIC_MAX_SIZE },
[VIRT_IMSIC_S] = { 0x28000000, VIRT_IMSIC_MAX_SIZE },
[VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 },
[VIRT_PCIE_MMIO] = { 0x40000000, 0x40000000 },
[VIRT_DRAM] = { 0x80000000, 0x0 }, / DDR空間 /
};

rt-smart針對virt board的ddr空間規劃

參考鏈接腳本

bspqemu-virt64-riscvlink.lds

以及board.h中的相關定義

bspqemu-virt64-riscvdriverboard.h

得到ddr的空間規劃如下

1.jpg

rt-smart針對virt board的初始化

整體初始化

rt_hw_board_init定義了與qemu-virt-riscv相關的板級初始化的全部內容,包括內存系統,plic中斷子系統,定時器系統以及串口設備等。它由rtthread_startup調用,完整的調用路徑如下。

(libcpurisc-vvirt64startup_gcc.S)_start->primary_cpu_entry->entry->rtthread_startup->rt_hw_board_init

源碼如下

void rt_hw_board_init(void)
{
#ifdef RT_USING_USERSPACE
rt_page_init(init_page_region);
/* init mmu_info structure */
rt_hw_mmu_map_init(&mmu_info, (void *)(USER_VADDR_START - IOREMAP_SIZE), IOREMAP_SIZE, (rt_size_t )MMUTable, 0);
// this API is reserved currently since PLIC etc had not been porting completely to MMU version
rt_hw_mmu_kernel_map_init(&mmu_info, 0x00000000UL, 0x80000000);
/
setup region, and enable MMU /
rt_hw_mmu_setup(&mmu_info, platform_mem_desc, NUM_MEM_DESC);
#endif
#ifdef RT_USING_HEAP
/
initialize memory system /
rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
#endif
plic_init();
rt_hw_interrupt_init();
rt_hw_uart_init();
#ifdef RT_USING_CONSOLE
/
set console device /
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif /
RT_USING_CONSOLE /
rt_hw_tick_init();
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
#ifdef RT_USING_HEAP
rt_kprintf("heap: [0x%08x - 0x%08x]n", (rt_ubase_t)RT_HW_HEAP_BEGIN, (rt_ubase_t)RT_HW_HEAP_END);
#endif /
RT_USING_HEAP */
}
rt_page_init

rt-smart中使用了buddy算法管理了一部分內存區域,系統使用page_alloc來向buddy管理的內存區域申請內存資源,像linux一樣每個page是4k的大小。

rt-smart采用buddy算法將系統中部分可用的物理內存頁面按照每1個頁面、2個頁面、4個頁面等等劃分為了不同的單元。

1.jpg

void rt_page_init(rt_region_t reg)
{
int i;
LOG_D("split 0x%08x 0x%08xn", reg.start, reg.end);
reg.start += ARCH_PAGE_MASK;
reg.start &= ~ARCH_PAGE_MASK;
reg.end &= ~ARCH_PAGE_MASK;
{
int nr = ARCH_PAGE_SIZE / sizeof(struct page);
int total = (reg.end - reg.start) >> ARCH_PAGE_SHIFT;
int mnr = (total + nr) / (nr + 1);
LOG_D("nr = 0x%08xn", nr);
LOG_D("total = 0x%08xn", total);
LOG_D("mnr = 0x%08xn", mnr);
RT_ASSERT(mnr < total);
page_start = (struct page*)reg.start;
reg.start += (mnr << ARCH_PAGE_SHIFT);
page_addr = (void*)reg.start;
page_nr = (reg.end - reg.start) >> ARCH_PAGE_SHIFT;
}

這里rt-smart直接將一部分頁表空間分配給struct page去使用,有可能會造成頁面的浪費。例如當total=7,
nr=5時,mnr=2,也就是倆個頁表用于存儲page,五個頁表是真正可以被alloc_page申請的。但實際上五個頁表只需要一個頁表的空間就可以存放page結構體了,相當于浪費了一個頁表。

rt_hw_mmu_map_init
#define USER_VADDR_START 0x100000000UL
#define IOREMAP_SIZE (1ul << 30)
int rt_hw_mmu_map_init(rt_mmu_info *mmu_info, void *v_address, rt_size_t size, rt_size_t *vtable, rt_size_t pv_off)
{
/ 代碼省略 /
mmu_info->vtable = vtable;
mmu_info->vstart = va_s;
mmu_info->vend = va_e;
mmu_info->pv_off = pv_off;
return 0;
}
mmu_info是一個全局變量,在調用rt_hw_mmu_map_init后,(USER_VADDR_START - IOREMAP_SIZE) ~ USER_VADDR_START 這片虛擬地址空間將來專門提供給ioremap來使用。也就是ioremap返回的虛擬地址區間就是
0xc0000000 ~ 0xFFFFFFFF

rt_hw_mmu_kernel_map_init
void rt_hw_mmu_kernel_map_init(rt_mmu_info *mmu_info, rt_size_t vaddr_start, rt_size_t size)
{
rt_size_t paddr_start = __UMASKVALUE(VPN_TO_PPN(vaddr_start, mmu_info->pv_off), PAGE_OFFSET_MASK);
rt_size_t va_s = GET_L1(vaddr_start);
rt_size_t va_e = GET_L1(vaddr_start + size - 1);
rt_size_t i;
for (i = va_s; i <= va_e; i++)
{
mmu_info->vtable[i] = COMBINEPTE(paddr_start, PAGE_ATTR_RWX | PTE_G | PTE_V);
paddr_start += L1_PAGE_SIZE;
}
rt_hw_cpu_tlb_invalidate();
}

這里將0x0 ~ 0x80000000的物理地址空間做了offset為0的一比一映射,且只使用了一級頁表。之后0x80000000之下的地址CPU都可以直接訪問了。從頁表的屬性配置上看,這片區域是nocache的。

rt_hw_mmu_setup
#define KERNEL_VADDR_START 0x80000000
#define PV_OFFSET 0
struct mem_desc platform_mem_desc[] = {
{KERNEL_VADDR_START, KERNEL_VADDR_START + 0x10000000 - 1, KERNEL_VADDR_START + PV_OFFSET, NORMAL_MEM},
};
void rt_hw_mmu_setup(rt_mmu_info *mmu_info, struct mem_desc *mdesc, int desc_nr)
{
void *err;
for (size_t i = 0; i < desc_nr; i++)
{
size_t attr;
switch (mdesc->attr)
{
case NORMAL_MEM:
attr = MMU_MAP_K_RWCB;
break;
case NORMAL_NOCACHE_MEM:
attr = MMU_MAP_K_RWCB;
break;
case DEVICE_MEM:
attr = MMU_MAP_K_DEVICE;
break;
default:
attr = MMU_MAP_K_DEVICE;
}
rt_kprintf("vaddr start:%lx paddr_start:%lxn", mdesc->vaddr_start, mdesc->paddr_start);
err = _rt_hw_mmu_map(mmu_info, (void *)mdesc->vaddr_start, (void *)mdesc->paddr_start,
mdesc->vaddr_end - mdesc->vaddr_start + 1, attr);
mdesc++;
}
rt_hw_mmu_switch((void *)MMUTable);
}

這里首先將0x80000000 ~ 0x90000000這片區域做了offset為0的線性映射,映射使用的是三級頁表一頁一頁映射的,相當于page的區域也被映射好了。之后調用rt_hw_mmu_switch配置SATP配置MMU的地址翻譯模式為SV39。STAP的mode被配置后,MMU就相當于開啟了。

將rtconfig.h中的PV_OFFSET改為非0值后系統無法啟動,對比bsp/qemu-vexpress-a9中board.c里關于頁表的配置這塊兒應該還是有問題的。

rt_hw_tick_init
int rt_hw_tick_init(void)
{
/* Read core id /
// unsigned long core_id = current_coreid();
unsigned long interval = 1000/RT_TICK_PER_SECOND;
/
Clear the Supervisor-Timer bit in SIE /
clear_csr(sie, SIP_STIP);
/
calculate the tick cycles /
// tick_cycles = interval * sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / CLINT_CLOCK_DIV / 1000ULL - 1;
tick_cycles = 40000;
/
Set timer /
sbi_set_timer(get_ticks() + tick_cycles);
/
Enable the Supervisor-Timer bit in SIE */
set_csr(sie, SIP_STIP);
return 0;
}

這里使用的是riscv中的mtime。mtime是riscv中定義的一個64位的系統計時器,它被要求工作在常開的時鐘域下。這里使用以下指令讀取mtime的值

static uint64_t get_ticks()
{
asmvolatile (
"rdtime %0"
: "=r"(time_elapsed));
return time_elapsed;
}
補充知識,在qemu中這個時鐘的獲取來源如下

static inline int64_t get_clock_realtime(void)
{
struct timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
}

sbi_set_timer并不是設置timer本身的值,而是設置機器模式計時器比較值寄存器MTIMECMPH, MTIMECMPL的值,
當系統計時器的值小于等于 {M/STIMECMPH[31:0],M/STIMECMPL[31:0]}的值時不產生中斷;當系統計時器的值大于 {M/STIMECMPH[31:0],M/STIMECMPL[31:0]} 的值時 CLINT產生對應的計時器中斷。

它的配置過程為rt-smart將比較寄存器的配置按規則組織為sbi_call的指令,將指令類型指令參數等放入cpu的a0~a7的寄存器,然后調用ecall指令使cpu陷入M態。

sbi_set_timer->SBI_CALL1(SBI_SET_TIMER, 0, val)->sbi_call

static __inline struct sbi_ret
sbi_call(uint64_t arg7, uint64_t arg6, uint64_t arg0, uint64_t arg1,
uint64_t arg2, uint64_t arg3, uint64_t arg4)
{
struct sbi_ret ret;
register uintptr_t a0 __asm("a0") = (uintptr_t)(arg0);
register uintptr_t a1 __asm("a1") = (uintptr_t)(arg1);
register uintptr_t a2 __asm("a2") = (uintptr_t)(arg2);
register uintptr_t a3 __asm("a3") = (uintptr_t)(arg3);
register uintptr_t a4 __asm("a4") = (uintptr_t)(arg4);
register uintptr_t a6 __asm("a6") = (uintptr_t)(arg6);
register uintptr_t a7 __asm("a7") = (uintptr_t)(arg7);
__asm __volatile(
"ecall"
: "+r"(a0), "+r"(a1)
: "r"(a2), "r"(a3), "r"(a4), "r"(a6), "r"(a7)
: "memory");
ret.error = a0;
ret.value = a1;
return (ret);
}

CPU陷入M態后,opensbi會處理這個ecall產生的異常。獲取內核放到寄存器中參數,把新的值賦值給比較值寄存器,并清除計時器中斷

void sbi_timer_event_start(u64 next_event)
{
if (timer_dev && timer_dev->timer_event_start)
timer_dev->timer_event_start(next_event);
csr_clear(CSR_MIP, MIP_STIP);
csr_set(CSR_MIE, MIP_MTIP);
}

其他

之后的初始化都是原先rt-thread中的內容了,感興趣的讀者可以自行查閱rt-thread官方的《RT-THREAD 編程指南》手冊來學習。另外需要注意的點在plic_init中,plic的寄存器的基地址沒有使用ioremap就直接使用了,這是因為上面描述的0x0 ~ 0x80000000的物理地址空間被做了offset為0的一比一映射。

rt-smart的ioremap實現
void *rt_ioremap(void *paddr, size_t size)
{
return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY);
}
void *rt_ioremap_nocache(void *paddr, size_t size)
{
return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY);
}
void *rt_ioremap_cached(void *paddr, size_t size)
{
return _ioremap_type(paddr, size, MM_AREA_TYPE_PHY_CACHED);
}

rt-smart中的ioremap實際上只分了倆種映射方式,分別是cache和nocache。在當前的qemu-virt64-riscv里,cache的屬性沒有配置到頁表中,我也沒有查qemu的頁表支不支持配置cache,感興趣的讀者請參考C906的相關代碼
libcpu/risc-v/t-head/c906/riscv_mmu.h

/* C-SKY extend /
#define PTE_SEC (1UL << 59) /
Security /
#define PTE_SHARE (1UL << 60) /
Shareable /
#define PTE_BUF (1UL << 61) /
Bufferable /
#define PTE_CACHE (1UL << 62) /
Cacheable /
#define PTE_SO (1UL << 63) /
Strong Order */
#define MMU_MAP_K_DEVICE (PAGE_ATTR_RWX | PTE_V | PTE_G | PTE_SO | PTE_BUF | PTE_A | PTE_D)
#define MMU_MAP_K_RWCB (PAGE_ATTR_RWX | PTE_V | PTE_G | PTE_SHARE | PTE_BUF | PTE_CACHE | PTE_A | PTE_D)
static void *_ioremap_type(void *paddr, size_t size, int type)
{
void *v_addr = NULL;
size_t attr;
switch (type)
{
case MM_AREA_TYPE_PHY:
attr = MMU_MAP_K_DEVICE;
break;
case MM_AREA_TYPE_PHY_CACHED:
attr = MMU_MAP_K_RWCB;
break;
default:
return v_addr;
}
rt_mm_lock();
v_addr = rt_hw_mmu_map(&mmu_info, 0, paddr, size, attr);
if (v_addr)
{
int ret = lwp_map_area_insert(&k_map_area, (size_t)v_addr, size, type);
if (ret != 0)
{
_iounmap_range(v_addr, size);
v_addr = NULL;
}
}
rt_mm_unlock();
return v_addr;
}

__ioremap_type中會記錄頁表要配置的屬性然后調用rt_hw_mmu_map進行映射。之后會將映射得到的虛擬地址插入到k_map_area中。

void *_rt_hw_mmu_map(rt_mmu_info *mmu_info, void *v_addr, void *p_addr, rt_size_t size, rt_size_t attr)
{
/ 代碼省略 /
if (v_addr)
{
/ 代碼省略 /
}
else
{
vaddr = find_vaddr(mmu_info, pages);
}
if (vaddr)
{
ret = __rt_hw_mmu_map(mmu_info, (void *)vaddr, p_addr, pages, attr);
if (ret == 0)
{
rt_hw_cpu_tlb_invalidate();
return (void *)(vaddr | GET_PF_OFFSET((rt_size_t)p_addr));
}
}
return 0;
}

ioremap傳入的虛擬地址是0,所以這里先需要調用find_vaddr得到一個可用的虛擬地址。另一個傳入find_vaddr的參數pages代表要要映射的物理內存區域需要多少個page(4K).

static size_t find_vaddr(rt_mmu_info *mmu_info, int pages)
{
size_t loop_pages;
size_t va;
size_t find_va = 0;
int n = 0;
size_t i;
loop_pages = (mmu_info->vend - mmu_info->vstart) ? (mmu_info->vend - mmu_info->vstart) : 1;
loop_pages <<= (ARCH_INDEX_WIDTH * 2);
va = mmu_info->vstart;
va <<= (ARCH_PAGE_SHIFT + ARCH_INDEX_WIDTH * 2);
for (i = 0; i < loop_pages; i++, va += ARCH_PAGE_SIZE) {
if (_rt_hw_mmu_v2p(mmu_info, (void *)va)) {
n = 0;
find_va = 0;
continue;
}
if (!find_va) {
find_va = va;
}
n++;
if (n >= pages) {
return find_va;
}
}
return 0;
}

這里會從mmu_info->vstart的虛擬地址開始找,這個地址就是最前面提到的0xC0000000。從0XC0000000開始一個page一個page的去找,看對應的虛擬地址有沒有被映射。如果沒有,那么將va賦值給find_va。

之后會繼續往后查找看能不能找到連續的虛擬內存空間大小可以滿足ioremap需要的大小。如果滿足大小最終就返回找到的虛擬地址。總結這個過程就是尋找一塊連續的沒有被映射的大小滿足的虛擬地址空間。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux系統
    +關注

    關注

    4

    文章

    595

    瀏覽量

    27470
  • 定時器
    +關注

    關注

    23

    文章

    3255

    瀏覽量

    115177
  • 虛擬機
    +關注

    關注

    1

    文章

    931

    瀏覽量

    28359
  • MMU
    MMU
    +關注

    關注

    0

    文章

    91

    瀏覽量

    18336
  • RT-Thread
    +關注

    關注

    31

    文章

    1305

    瀏覽量

    40313
收藏 人收藏

    評論

    相關推薦

    RT-Smart的資料合集

    1、RT-Smart的啟動過程熟悉 RT-Smart 架構的過程,研究其啟動過程的是必不可少的,那么系統正常運行之前,需要做哪些準備工
    發表于 03-22 15:06

    RT-Smart用戶態運行LVGL的操作流程

    開發流程1、RT-Smart 環境搭下載 RT-Smart 用戶態應用代碼進入到 userapps 目錄,克隆 RT-Thread rt-smart
    發表于 11-18 11:34

    RT-Smartriscv64上的系統初始化和異常處理的代碼注釋

    RT-Smart riscv64匯編注釋以rt-smart全志D1上的代碼為例,主要注釋了rt-smart
    發表于 02-10 16:43

    rt-smartriscv64上的系統初始化和異常處理的代碼注釋

    rt-smart全志D1上的代碼為例,主要注釋了rt-smartriscv64上的系統初始化
    發表于 02-15 11:04

    Rt-Smartriscv初始化流程

    的相關定義bsp\\qemu-virt64-riscv\\driver\\board.h得到ddr的空間規劃如下rt-smart針對virt board的初始化整體初始化
    發表于 02-16 14:09

    樹莓派上rt-smart的應用編程入門

    文章,一些介紹及樹莓派上rt-smart的應用編程入門(更多的從應用程序角度入手)。后續還包括rt-smart上的不同應用程序介紹: wget curl移植 busybox移植 sdl圖形類
    的頭像 發表于 05-13 14:10 ?3212次閱讀
    樹莓派上<b class='flag-5'>rt-smart</b>的應用編程入門

    RT-Thread全球技術大會:如何使用組件以及自動初始化流程

    RT-Thread全球技術大會:如何使用組件和自動初始化流程 ? ? ? ? ? 審核編輯:彭靜
    的頭像 發表于 05-27 15:16 ?969次閱讀
    <b class='flag-5'>RT</b>-Thread全球技術大會:如何使用組件以及自動<b class='flag-5'>初始化</b><b class='flag-5'>流程</b>

    RT-Thread自動初始化機制

    ??分析之前首先查閱 RT-Thread 的官方文檔 [RT-Thread 自動初始化機制](https://www.rt-thread.
    的頭像 發表于 06-17 08:52 ?2737次閱讀
    <b class='flag-5'>RT</b>-Thread自動<b class='flag-5'>初始化</b>機制

    RT-Smart初始化相關功能及物理頁分配算法伙伴系統的實現

    想要對 RT-Smart 的物理頁內存管理功能有所了解,需要熟悉相關代碼。
    的頭像 發表于 10-19 10:05 ?1430次閱讀

    優雅的D1S上運行RT-Smart

    前言 最近在學習 RT-Smart ,正巧有全志開發者論壇看到這么一篇帖子【驚】麻雀上運行國產rt-smart系統,看到很多人都在關注 D1S
    的頭像 發表于 11-16 20:15 ?2946次閱讀

    絲滑的RT-Smart用戶態運行LVGL

    開發流程 1、RT-Smart 環境搭建 下載 RT-Smart 用戶態應用代碼: 1 git?clone?https: //github.com/RT-Thread/userapps
    的頭像 發表于 11-22 20:20 ?1301次閱讀

    RT-Smart riscv64匯編注釋

    rt-smart全志D1上的代碼為例,主要注釋了rt-smartriscv64上的系統初始化
    的頭像 發表于 02-08 21:40 ?1195次閱讀

    riscvrt-smart的板級初始化

    本文章的代碼來自于rt-smart針對qemu-virt-riscv的bsp 倉庫地址 https://gitee.com/rtthread/rt-thread/tree/
    的頭像 發表于 02-09 17:45 ?1015次閱讀

    riscvrt-smart的板級初始化

    Virt板不對應于任何真實硬件的平臺;它是為虛擬機設計的。如果你只是想運行Linux等客戶機,而不關心重現真實世界硬件的特殊性和局限性,那么它是推薦的板卡類型。(摘自https://www.qemu.org/docs/master/system/riscv/virt.html)
    的頭像 發表于 02-09 17:44 ?844次閱讀

    RT-Smart riscv64匯編注釋

    rt-smart全志D1上的代碼為例,主要注釋了rt-smartriscv64上的系統初始化
    的頭像 發表于 10-12 17:26 ?640次閱讀
    <b class='flag-5'>RT-Smart</b> <b class='flag-5'>riscv</b>64匯編注釋
    主站蜘蛛池模板: 欧美成人无码视频午夜福利 | qvod 电影| 国偷自产视频一区二区99 | 2020国产成人精品视频人 | 无码区国产区在线播放 | 艳鉧动漫1~6全集观看在线 | 久久久久国产精品美女毛片 | 日韩欧美一区二区三区在线视频 | 狠狠色狠狠色综合日日92 | 美女坐脸vk| 午夜色网站 | 亚洲欧美自拍清纯中文字幕 | 2018久久视频在线视频观看 | 秋霞电影网午夜鲁丝片无码 | 免费国产成人高清在线观看视频 | 狠狠色狠狠色综合系列 | 岳扒开让我添 | 9420高清完整版在线电影免费观看 | 三级网站视频在线观看 | 国产亚洲精品久久精品录音 | av在线观看网站免费 | 男人狂躁进女人免费视频公交 | 久久久无码精品无码国产人妻丝瓜 | 国产成人免费高清视频 | 黑人猛挺进小莹的体内视频 | 亚洲AV噜噜狠狠网址蜜桃尤物 | 日韩AV无码一区二区三区不卡毛片 | 三级网站视频在线观看 | 国产精品久久久久久久伊一 | 可以看的黄页的网站 | 亚洲第一页在线播放 | 亚洲综合春色另类久久 | 巨爆乳中文字幕爆乳区 | 激情床戏视频片段有叫声 | 亚洲色在线 | 国产偷国产偷亚州清高 | 色橹橹欧美在线观看视频高 | 色久久久综合88一本道 | 野花日本免费完整版高清版动漫 | 一二三四在线高清中文版免费观看电影 | 亚洲蜜桃AV永久无码精品放毛片 |